diff --git a/.hgignore b/.hgignore
index 501f9e6abe6fbe80f07c8688e75e09f855c29104..b3670902270feeb9c8db67c0079228467b59722d 100644
--- a/.hgignore
+++ b/.hgignore
@@ -25,6 +25,7 @@ indra/lib/mono/indra/*.exe
 indra/lib/mono/indra/*.pdb
 indra/lib/python/eventlet/
 indra/llwindow/glh/glh_linear.h
+indra/newview/app_settings/dictionaries
 indra/newview/app_settings/mozilla
 indra/newview/app_settings/mozilla-runtime-*
 indra/newview/app_settings/mozilla_debug
diff --git a/.hgtags b/.hgtags
index 6dd9a0e1119031f1906168a6200545d883b4ccd4..0bca1f09abecabefff85f44fa43bf0f0fc795645 100644
--- a/.hgtags
+++ b/.hgtags
@@ -264,6 +264,7 @@ c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
 16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
 37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
 16f8e2915f3f2e4d732fb3125daf229cb0fd1875 3.2.8-beta1
+089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
 987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
 987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
 51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
@@ -286,6 +287,9 @@ d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
 28b95a6a28dca3338d9a1f4f204b96678df9f6a5 viewer-beta-candidate
 b43cd25be49e3984ff5361cefad020e069131d98 3.3.1-start
 3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 DRTVWR-125
+dffd0457ee0745de65bf95f0642a5c9e46b8e2f0 viewer-beta-candidate
+3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 viewer-beta-candidate
+3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 viewer-beta-candidate
 3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 3.3.1-start
 28b95a6a28dca3338d9a1f4f204b96678df9f6a5 3.3.1-beta1
 1dc545e44617975da2a4a32fe303386c687a6ca1 viewer-beta-candidate
@@ -300,7 +304,13 @@ c623bbc854b6f7ee1b33a3718f76715046aa2937 viewer-release-candidate
 675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
 675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-release
 675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
+050e48759337249130f684b4a21080b683f61732 DRTVWR-168
+b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
+c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
+600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
 600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
+9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
+a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
 24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
 15e90b52dc0297921b022b90d10d797436b8a1bd viewer-release-candidate
 6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
@@ -317,3 +327,6 @@ fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
 af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
 4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
 6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
+09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
+f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 3.3.4-beta1
+f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
diff --git a/BuildParams b/BuildParams
index 6f1af583f0a76171e8337db8dcb594c3163ba4d0..3dd35c5863324903337ddd6a518b111e3bf51e4d 100644
--- a/BuildParams
+++ b/BuildParams
@@ -112,6 +112,17 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"
 viewer-mesh.viewer_grid = aditi
 viewer-mesh.email = shining@lists.lindenlab.com
 
+# ========================================
+# viewer-adult-check
+# ========================================
+
+viewer-adult-check.viewer_channel = "Project Viewer - AdultCheck"
+viewer-adult-check.login_channel = "Project Viewer - AdultCheck"
+viewer-adult-check.viewer_grid = agni
+viewer-adult-check.build_debug_release_separately = true
+viewer-adult-check.build_CYGWIN_Debug = false
+viewer-adult-check.build_viewer_update_version_manager = false
+
 # ================
 # oz
 # ================
@@ -138,6 +149,10 @@ oz_viewer-beta-review.viewer_channel = "Second Life Beta Viewer"
 oz_viewer-beta-review.login_channel = "Second Life Beta Viewer"
 oz_viewer-beta-review.email = oz@lindenlab.com
 
+oz_project-7.build_debug_release_separately = true
+oz_project-7.codeticket_add_context = false
+oz_project-7.email = "sldev@catznip.com oz@lindenlab.com"
+
 # =================================================================
 # asset delivery 2010 projects
 # =================================================================
diff --git a/autobuild.xml b/autobuild.xml
index ba57d09f86f2b723c003ebc81807d2e7f0cb2bfb..9b564ddefce9fdea8e1122531f0e3b668160e073 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -363,6 +363,54 @@
           </map>
         </map>
       </map>
+      <key>dictionaries</key>
+      <map>
+        <key>license</key>
+        <string>various open</string>
+        <key>license_file</key>
+        <string>LICENSES/dictionaries.txt</string>
+        <key>name</key>
+        <string>dictionaries</string>
+        <key>platforms</key>
+        <map>
+          <key>darwin</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>06a6c49eb1873e95623d3d2d07aee903</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/Darwin/installer/dictionaries-1-darwin-20120616.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin</string>
+          </map>
+          <key>linux</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>4f0ca21d27e0cd0b002149062b0a4b25</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/Linux/installer/dictionaries-1-linux-20120616.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>linux</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>7520d75f6af325328322201c888191d4</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/CYGWIN/installer/dictionaries-1-windows-20120616.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+        </map>
+      </map>
       <key>elfio</key>
       <map>
         <key>license</key>
@@ -999,6 +1047,54 @@
           </map>
         </map>
       </map>
+      <key>libhunspell</key>
+      <map>
+        <key>license</key>
+        <string>libhunspell</string>
+        <key>license_file</key>
+        <string>LICENSES/hunspell.txt</string>
+        <key>name</key>
+        <string>libhunspell</string>
+        <key>platforms</key>
+        <map>
+          <key>darwin</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>6f5db0ef258df6e5c93c843ec559db6d</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/Darwin/installer/libhunspell-1.3.2-darwin-20120616.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin</string>
+          </map>
+          <key>linux</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>0c432d2626aea2e91a56335879c92965</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/Linux/installer/libhunspell-1.3.2-linux-20120616.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>linux</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>6a140e5620826aa5e587b4157f57b389</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/CYGWIN/installer/libhunspell-1.3.2-windows-20120616.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+        </map>
+      </map>
       <key>libpng</key>
       <map>
         <key>license</key>
@@ -1099,8 +1195,6 @@
       <map>
         <key>license</key>
         <string>havok</string>
-        <key>license_file</key>
-        <string>on_file</string>
         <key>name</key>
         <string>llconvexdecomposition</string>
         <key>platforms</key>
@@ -1762,8 +1856,12 @@
     </map>
     <key>package_description</key>
     <map>
+      <key>description</key>
+      <string>Spell checking dictionaries</string>
+      <key>license</key>
+      <string>various open</string>
       <key>name</key>
-      <string>viewer_development</string>
+      <string>dictionaries</string>
       <key>platforms</key>
       <map>
         <key>common</key>
@@ -2473,6 +2571,8 @@
           <string>windows</string>
         </map>
       </map>
+      <key>version</key>
+      <string>1.0</string>
     </map>
     <key>type</key>
     <string>autobuild</string>
diff --git a/build.sh b/build.sh
index 8ca3208087f6a4729a1f8a991e86f08832a40a26..a95ca91d82970997e753c61437ce948b277a31ee 100755
--- a/build.sh
+++ b/build.sh
@@ -15,6 +15,12 @@
 # * The basic convention is that the build name can be mapped onto a mercurial URL,
 #   which is also used as the "branch" name.
 
+check_for()
+{
+    if [ -e "$2" ]; then found_dict='FOUND'; else found_dict='MISSING'; fi
+    echo "$1 ${found_dict} '$2' " 1>&2
+}
+
 build_dir_Darwin()
 {
   echo build-darwin-i386
@@ -59,6 +65,8 @@ pre_build()
     && [ -r "$master_message_template_checkout/message_template.msg" ] \
     && template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
 
+    check_for "Before 'autobuild configure'" ${build_dir}/packages/dictionaries
+
     "$AUTOBUILD" configure -c $variant -- \
      -DPACKAGE:BOOL=ON \
      -DRELEASE_CRASH_REPORTING:BOOL=ON \
@@ -67,7 +75,10 @@ pre_build()
      -DGRID:STRING="\"$viewer_grid\"" \
      -DLL_TESTS:BOOL="$run_tests" \
      -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
- end_section "Pre$variant"
+
+    check_for "After 'autobuild configure'" ${build_dir}/packages/dictionaries
+
+  end_section "Pre$variant"
 }
 
 build()
@@ -76,12 +87,17 @@ build()
   if $build_viewer
   then
     begin_section "Viewer$variant"
+
+    check_for "Before 'autobuild build'" ${build_dir}/packages/dictionaries
+
     if "$AUTOBUILD" build --no-configure -c $variant
     then
       echo true >"$build_dir"/build_ok
     else
       echo false >"$build_dir"/build_ok
     fi
+    check_for "After 'autobuild configure'" ${build_dir}/packages/dictionaries
+
     end_section "Viewer$variant"
   fi
 }
@@ -172,7 +188,10 @@ eval "$("$AUTOBUILD" source_environment)"
 # dump environment variables for debugging
 env|sort
 
+check_for "Before 'autobuild install'" ${build_dir}/packages/dictionaries
+
 
+check_for "After 'autobuild install'" ${build_dir}/packages/dictionaries
 # Now run the build
 succeeded=true
 build_processes=
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 18df538d2a9f66e246f1824ae10ed75993369c52..df504e4a8a544ed726b7caa24259e1f4d482c71f 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -297,6 +297,8 @@ Cherry Cheevers
 ChickyBabes Zuzu
 Christopher  Organiser
 Ciaran Laval
+Cinder Roxley
+    STORM-1703
 Clara Young
 Coaldust Numbers
     VWR-1095
@@ -471,6 +473,7 @@ Hiro Sommambulist
 	VWR-143
 Hitomi Tiponi
 	STORM-1741
+	STORM-1862
 Holger Gilruth
 Horatio Freund
 Hoze Menges
@@ -623,12 +626,22 @@ Jonathan Yap
 	STORM-1799
 	STORM-1796
 	STORM-1807
+	STORM-1812
+	STORM-1820
+	STORM-1839
+	STORM-1842
 	STORM-1808
 	STORM-637
 	STORM-1822
 	STORM-1809
 	STORM-1793
 	STORM-1810
+	STORM-1860
+	STORM-1852
+	STORM-1870
+	STORM-1872
+	STORM-1858
+	STORM-1862
 Kadah Coba
 	STORM-1060
 Jondan Lundquist
@@ -725,6 +738,8 @@ Marc2 Sands
 Marianne McCann
 Marine Kelley
     STORM-281
+MartinRJ Fayray
+    STORM-1845
 Matthew Anthony
 Matthew Dowd
 	VWR-1344
@@ -1052,6 +1067,8 @@ Simon Nolan
 Sini Nubalo
 Sitearm Madonna
 SLB Wirefly
+Slee Mayo
+    SEC-1075
 snowy Sidran
 SpacedOut Frye
 	VWR-34
@@ -1287,6 +1304,7 @@ Zi Ree
 	VWR-24017
 	VWR-25588
 	STORM-1790
+	STORM-1842
 Zipherius Turas
 	VWR-76
 	VWR-77
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 279d577a278a805f06442f2ba63bf580eadbed59..9b836aac5fb2772d93136b9d7d6ef13bb6518a4e 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -37,6 +37,7 @@ set(cmake_SOURCE_FILES
     GLOD.cmake
     GStreamer010Plugin.cmake
     GooglePerfTools.cmake
+    Hunspell.cmake
     JPEG.cmake
     LLAddBuildTest.cmake
     LLAudio.cmake
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 394db362b1572414e80578e5f433589b6b2b9f77..224e0a8b5163a32b4efbfd941113dcc0402ef12b 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -41,6 +41,7 @@ if(WINDOWS)
         libeay32.dll
         libcollada14dom22-d.dll
         glod.dll    
+        libhunspell.dll
         )
 
     set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
@@ -53,6 +54,7 @@ if(WINDOWS)
         libeay32.dll
         libcollada14dom22.dll
         glod.dll
+        libhunspell.dll
         )
 
     if(USE_GOOGLE_PERFTOOLS)
@@ -212,11 +214,12 @@ elseif(DARWIN)
         libexpat.1.5.2.dylib
         libexpat.dylib
         libGLOD.dylib
-    libllqtwebkit.dylib
-    libminizip.a
+        libllqtwebkit.dylib
+        libminizip.a
         libndofdev.dylib
+        libhunspell-1.3.0.dylib
         libexception_handler.dylib
-    libcollada14dom.dylib
+        libcollada14dom.dylib
        )
 
     # fmod is statically linked on darwin
@@ -257,14 +260,15 @@ 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
         libgobject-2.0.so
         libgtest_main.so
         libgtest.so.0
-    libminizip.so
+        libhunspell-1.3.so.0.0.0
+        libminizip.so
         libopenal.so
         libopenjpeg.so
         libssl.so
diff --git a/indra/cmake/FindHUNSPELL.cmake b/indra/cmake/FindHUNSPELL.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6faf22959c65ab189f5c10e3b3afdfaba00bd973
--- /dev/null
+++ b/indra/cmake/FindHUNSPELL.cmake
@@ -0,0 +1,38 @@
+# -*- cmake -*-
+
+# - Find HUNSPELL
+# This module defines
+#  HUNSPELL_INCLUDE_DIR, where to find libhunspell.h, etc.
+#  HUNSPELL_LIBRARY, the library needed to use HUNSPELL.
+#  HUNSPELL_FOUND, If false, do not try to use HUNSPELL.
+
+find_path(HUNSPELL_INCLUDE_DIR hunspell.h
+  PATH_SUFFIXES hunspell
+  )
+
+set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3.0 libhunspell)
+find_library(HUNSPELL_LIBRARY
+  NAMES ${HUNSPELL_NAMES}
+  )
+
+if (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
+  set(HUNSPELL_FOUND "YES")
+else (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
+  set(HUNSPELL_FOUND "NO")
+endif (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
+
+
+if (HUNSPELL_FOUND)
+  if (NOT HUNSPELL_FIND_QUIETLY)
+    message(STATUS "Found Hunspell: Library in '${HUNSPELL_LIBRARY}' and header in '${HUNSPELL_INCLUDE_DIR}' ")
+  endif (NOT HUNSPELL_FIND_QUIETLY)
+else (HUNSPELL_FOUND)
+  if (HUNSPELL_FIND_REQUIRED)
+    message(FATAL_ERROR " * * *\nCould not find HUNSPELL library! * * *")
+  endif (HUNSPELL_FIND_REQUIRED)
+endif (HUNSPELL_FOUND)
+
+mark_as_advanced(
+  HUNSPELL_LIBRARY
+  HUNSPELL_INCLUDE_DIR
+  )
diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0c9cf933161c5efab2c787c877bf069fd838f6a4
--- /dev/null
+++ b/indra/cmake/Hunspell.cmake
@@ -0,0 +1,22 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+set(HUNSPELL_FIND_QUIETLY ON)
+set(HUNSPELL_FIND_REQUIRED ON)
+
+if (STANDALONE)
+  include(FindHUNSPELL)
+else (STANDALONE)
+  use_prebuilt_binary(libhunspell)
+  if (WINDOWS)
+    set(HUNSPELL_LIBRARY libhunspell)
+  elseif(DARWIN)
+    set(HUNSPELL_LIBRARY hunspell-1.3.0)
+  elseif(LINUX)
+    set(HUNSPELL_LIBRARY hunspell-1.3)
+  else()
+    message(FATAL_ERROR "Invalid platform")
+  endif()
+  set(HUNSPELL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/hunspell)
+  use_prebuilt_binary(dictionaries)
+endif (STANDALONE)
diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake
index df013b1665058e458ede89172c2aa5281ea480a5..f907181929802ab0a27019b574a3ddab7d4e1794 100644
--- a/indra/cmake/ViewerMiscLibs.cmake
+++ b/indra/cmake/ViewerMiscLibs.cmake
@@ -2,6 +2,7 @@
 include(Prebuilt)
 
 if (NOT STANDALONE)
+  use_prebuilt_binary(libhunspell)
   use_prebuilt_binary(libuuid)
   use_prebuilt_binary(slvoice)
   use_prebuilt_binary(fontconfig)
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 633ad84159e68403bdc123152dd50509ecf851e6..91c9f20c107f51f4e6c54a29d7a4fdb3db4765d6 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -18,6 +18,7 @@ include(LLWindow)
 include(LLUI)
 include(LLVFS)        # ugh, needed for LLDir
 include(LLXML)
+include(Hunspell)
 include(Linking)
 # include(Tut)
 
@@ -31,6 +32,7 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
+    ${LIBS_PREBUILD_DIR}/include/hunspell
     )
 
 set(llui_libtest_SOURCE_FILES
@@ -78,6 +80,7 @@ target_link_libraries(llui_libtest
     ${LLIMAGEJ2COJ_LIBRARIES}
     ${OS_LIBRARIES}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
+    ${HUNSPELL_LIBRARY}
     )
 
 if (WINDOWS)
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index e295e3c621d7788fc6ac1475fe57965e7da463a9..8276ec836a77399ed164ff02d4ec65a3286aafb5 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -269,6 +269,7 @@ namespace
 		virtual LLSD::UUID		asUUID() const	{ return LLUUID(mValue); }
 		virtual LLSD::Date		asDate() const	{ return LLDate(mValue); }
 		virtual LLSD::URI		asURI() const	{ return LLURI(mValue); }
+		virtual int				size() const	{ return mValue.size(); }
 	};
 	
 	LLSD::Integer	ImplString::asInteger() const
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index f4c43bac61f80e731842b260fd291e0c57422805..ed9284d2c51de8b227d49298f82752d1e4bab8b8 100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -44,6 +44,15 @@ template <class Object> class LLStrider
 	const LLStrider<Object>& operator =  (Object *first)    { mObjectp = first; return *this;}
 	void setStride (S32 skipBytes)	{ mSkip = (skipBytes ? skipBytes : sizeof(Object));}
 
+	LLStrider<Object> operator+(const S32& index) 
+	{
+		LLStrider<Object> ret;
+		ret.mBytep = mBytep + mSkip*index;
+		ret.mSkip = mSkip;
+
+		return ret;
+	}
+
 	void skip(const U32 index)     { mBytep += mSkip*index;}
 	U32 getSkip() const			   { return mSkip; }
 	Object* get()                  { return mObjectp; }
@@ -51,6 +60,7 @@ template <class Object> class LLStrider
 	Object& operator *()           { return *mObjectp; }
 	Object* operator ++(int)       { Object* old = mObjectp; mBytep += mSkip; return old; }
 	Object* operator +=(int i)     { mBytep += mSkip*i; return mObjectp; }
+
 	Object& operator[](U32 index)  { return *(Object*)(mBytep + (mSkip * index)); }
 };
 
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 09733e8e2a16cb3d8eb0b11175f9a89b84282b61..119efc795755ced045686dd04edab1387ac42260 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -183,6 +183,9 @@ class LL_COMMON_API LLStringOps
 	static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; }
 	static bool isPunct(llwchar a) { return iswpunct(a) != 0; }
 
+	static bool isAlpha(char a) { return isalpha((unsigned char)a) != 0; }
+	static bool isAlpha(llwchar a) { return iswalpha(a) != 0; }
+
 	static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
 	static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
 
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index bfb30f900f08df192cdc3cba46278a46bc3851a5..22d0aba51b7c15abe4e4b67a2a3020951be3dffe 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -29,7 +29,7 @@
 
 const S32 LL_VERSION_MAJOR = 3;
 const S32 LL_VERSION_MINOR = 3;
-const S32 LL_VERSION_PATCH = 3;
+const S32 LL_VERSION_PATCH = 4;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index e36d0b20d2fe8e37e11123e08c565cd4c332694c..f0b2caca3db02e56559662ffb8a0a3084b9db277 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -45,7 +45,7 @@ const S32 PARCEL_UNIT_AREA			= 16;
 const F32 PARCEL_HEIGHT = 50.f;
 
 //Height above ground which parcel boundries exist for explicitly banned avatars
-const F32 BAN_HEIGHT = 768.f;
+const F32 BAN_HEIGHT = 5000.f;
 
 // Maximum number of entries in an access list
 const S32 PARCEL_MAX_ACCESS_LIST = 300;
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 9297bcbac28344d3c72bb8afb0ec8ab896355149..b93f89d674fce1c4a916d36ff199842e0256ce0f 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -85,7 +85,7 @@ const F32	F_ALMOST_ONE	= 1.0f - F_ALMOST_ZERO;
 const F32 FP_MAG_THRESHOLD = 0.0000001f;
 
 // TODO: Replace with logic like is_approx_equal
-inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
+inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
 
 // These functions work by interpreting sign+exp+mantissa as an unsigned
 // integer.
@@ -111,13 +111,13 @@ inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <
 // WARNING: Infinity is comparable with F32_MAX and negative 
 // infinity is comparable with F32_MIN
 
-inline BOOL is_approx_equal(F32 x, F32 y)
+inline bool is_approx_equal(F32 x, F32 y)
 {
 	const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
 	return (std::abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);
 }
 
-inline BOOL is_approx_equal(F64 x, F64 y)
+inline bool is_approx_equal(F64 x, F64 y)
 {
 	const S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
 	return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 76cf9de613e3fc3d6c98d82d819436506c4659ce..2e6f9e2f719e4745e03bf7b73e8fb4075b6f2bd5 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -54,6 +54,7 @@ class LLVolumeTriangle;
 #include "llstrider.h"
 #include "v4coloru.h"
 #include "llrefcount.h"
+#include "llpointer.h"
 #include "llfile.h"
 
 //============================================================================
@@ -919,6 +920,10 @@ class LLVolumeFace
 	LLVector2*  mTexCoords;
 	U16* mIndices;
 
+	//vertex buffer filled in by LLFace to cache this volume face geometry in vram 
+	// (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer)
+	mutable LLPointer<LLRefCount> mVertexBuffer; 
+
 	std::vector<S32>	mEdge;
 
 	//list of skin weights for rigged volumes
diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp
index 3d8ca2ad9f19c3a58a7271598c32f8612ad8419a..a6fccd2a5660c21209289681467c6d84aa3d558b 100644
--- a/indra/llmessage/llsdmessagereader.cpp
+++ b/indra/llmessage/llsdmessagereader.cpp
@@ -276,7 +276,7 @@ S32 getElementSize(const LLSD& llsd)
 	case LLSD::TypeReal:
 		return sizeof(F64);
 	case LLSD::TypeString:
-		return llsd.asString().size();
+		return llsd.size();
 	case LLSD::TypeUUID:
 		return sizeof(LLUUID);
 	case LLSD::TypeDate:
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 45a3b18179a8aff6b2646aaf02e5aea96bf05add..362452d837fac8e6815c14fe4e93752ca8f9e62d 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -81,7 +81,7 @@ void LLCubeMap::initGL()
 		{
 			U32 texname = 0;
 			
-			LLImageGL::generateTextures(1, &texname);
+			LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, GL_RGB8, 1, &texname);
 
 			for (int i = 0; i < 6; i++)
 			{
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index fccbf37a8dd407f0a37c093ab931f977ef106d88..4dc2fcd7146d9e3f60474dcf803f2402de93acc7 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -422,6 +422,16 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y
 }
 
 // font metrics - override for LLFontFreetype that returns units of virtual pixels
+F32 LLFontGL::getAscenderHeight() const
+{ 
+	return mFontFreetype->getAscenderHeight() / sScaleY;
+}
+
+F32 LLFontGL::getDescenderHeight() const
+{ 
+	return mFontFreetype->getDescenderHeight() / sScaleY;
+}
+
 S32 LLFontGL::getLineHeight() const
 { 
 	return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 74bdbb43e7424497820c08353b7125e81295ba3f..5ed5d2c4ebe1bce1f51656a5a5f10b8fbdf3371b 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -115,6 +115,8 @@ class LLFontGL
 	S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
 
 	// font metrics - override for LLFontFreetype that returns units of virtual pixels
+	F32 getAscenderHeight() const;
+	F32 getDescenderHeight() const;
 	S32 getLineHeight() const;
 
 	S32 getWidth(const std::string& utf8text) const;
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 628a8d6131e1621dc51e6db2cd93a18127ee4f37..0b56b3889c90eed03253981e3bc18ed81496ed30 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -249,6 +249,12 @@ PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
 PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
 PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
 
+//transform feedback (4.0 core)
+PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
+PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
+
 //GL_ARB_debug_output
 PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
 PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
@@ -421,6 +427,7 @@ LLGLManager::LLGLManager() :
 	mHasDrawBuffers(FALSE),
 	mHasTextureRectangle(FALSE),
 	mHasTextureMultisample(FALSE),
+	mHasTransformFeedback(FALSE),
 	mMaxSampleMaskWords(0),
 	mMaxColorTextureSamples(0),
 	mMaxDepthTextureSamples(0),
@@ -558,7 +565,8 @@ bool LLGLManager::initGL()
 	parse_gl_version( &mDriverVersionMajor, 
 		&mDriverVersionMinor, 
 		&mDriverVersionRelease, 
-		&mDriverVersionVendorString );
+		&mDriverVersionVendorString,
+		&mGLVersionString);
 
 	mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
 
@@ -938,7 +946,6 @@ void LLGLManager::initExtensions()
 	mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
 	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
 	mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
-	mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
 	mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
 	mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
 	glh_init_extensions("GL_ARB_texture_cube_map");
@@ -963,11 +970,14 @@ void LLGLManager::initExtensions()
 							ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
 #endif
 	
+	mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
+
 	mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
 	mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
 	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
 	mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
 	mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
+	mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
 #if !LL_DARWIN
 	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
 #endif
@@ -1207,7 +1217,14 @@ void LLGLManager::initExtensions()
 		glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
 		glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
 		glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
-	}	
+	}
+	if (mHasTransformFeedback)
+	{
+		glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
+		glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
+		glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
+		glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
+	}
 	if (mHasDebugOutput)
 	{
 		glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
@@ -1964,6 +1981,7 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
 			case GL_COLOR_MATERIAL:
 			case GL_FOG:
 			case GL_LINE_STIPPLE:
+			case GL_POLYGON_STIPPLE:
 				mState = 0;
 				break;
 		}
@@ -2052,7 +2070,7 @@ void LLGLManager::initGLStates()
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
+void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string )
 {
 	// GL_VERSION returns a null-terminated string with the format: 
 	// <major>.<minor>[.<release>] [<vendor specific>]
@@ -2068,6 +2086,8 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
 		return;
 	}
 
+	version_string->assign(version);
+
 	std::string ver_copy( version );
 	S32 len = (S32)strlen( version );	/* Flawfinder: ignore */
 	S32 i = 0;
@@ -2429,3 +2449,65 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip()
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 }
 
+
+	
+LLGLSyncFence::LLGLSyncFence()
+{
+#ifdef GL_ARB_sync
+	mSync = 0;
+#endif
+}
+
+LLGLSyncFence::~LLGLSyncFence()
+{
+#ifdef GL_ARB_sync
+	if (mSync)
+	{
+		glDeleteSync(mSync);
+	}
+#endif
+}
+
+void LLGLSyncFence::placeFence()
+{
+#ifdef GL_ARB_sync
+	if (mSync)
+	{
+		glDeleteSync(mSync);
+	}
+	mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+#endif
+}
+
+bool LLGLSyncFence::isCompleted()
+{
+	bool ret = true;
+#ifdef GL_ARB_sync
+	if (mSync)
+	{
+		GLenum status = glClientWaitSync(mSync, 0, 1);
+		if (status == GL_TIMEOUT_EXPIRED)
+		{
+			ret = false;
+		}
+	}
+#endif
+	return ret;
+}
+
+void LLGLSyncFence::wait()
+{
+#ifdef GL_ARB_sync
+	if (mSync)
+	{
+		while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
+		{ //track the number of times we've waited here
+			static S32 waits = 0;
+			waits++;
+		}
+	}
+#endif
+}
+
+
+
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 5a33c98708356aa974c4bced60f4a91e89a0921b..964495a3abce301eae301d196b1e3d917d0820db 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -104,6 +104,7 @@ class LLGLManager
 	BOOL mHasDepthClamp;
 	BOOL mHasTextureRectangle;
 	BOOL mHasTextureMultisample;
+	BOOL mHasTransformFeedback;
 	S32 mMaxSampleMaskWords;
 	S32 mMaxColorTextureSamples;
 	S32 mMaxDepthTextureSamples;
@@ -141,6 +142,7 @@ class LLGLManager
 	S32 mGLSLVersionMajor;
 	S32 mGLSLVersionMinor;
 	std::string mDriverVersionVendorString;
+	std::string mGLVersionString;
 
 	S32 mVRAM; // VRAM in MB
 	S32 mGLMaxVertexRange;
@@ -417,13 +419,38 @@ class LLGLUpdate
 	virtual void updateGL() = 0;
 };
 
+const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000;  //1 ms
+
+class LLGLFence
+{
+public:
+	virtual void placeFence() = 0;
+	virtual bool isCompleted() = 0;
+	virtual void wait() = 0;
+};
+
+class LLGLSyncFence : public LLGLFence
+{
+public:
+#ifdef GL_ARB_sync
+	GLsync mSync;
+#endif
+	
+	LLGLSyncFence();
+	virtual ~LLGLSyncFence();
+
+	void placeFence();
+	bool isCompleted();
+	void wait();
+};
+
 extern LLMatrix4 gGLObliqueProjectionInverse;
 
 #include "llglstates.h"
 
 void init_glstates();
 
-void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
+void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
 
 extern BOOL gClothRipple;
 extern BOOL gHeadlessClient;
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index d61ec707f06c56f9c6c6ad3a56b0e0b480cfd5cd..a0727b8686dbbb2661a70b6e88a91d163c28924f 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -528,6 +528,13 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
 extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
 extern PFNGLSAMPLEMASKIPROC glSampleMaski;
 
+//transform feedback (4.0 core)
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+
+
 #elif LL_WINDOWS
 //----------------------------------------------------------------------------
 // LL_WINDOWS
@@ -759,6 +766,12 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
 extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
 extern PFNGLSAMPLEMASKIPROC glSampleMaski;
 
+//transform feedback (4.0 core)
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+
 //GL_ARB_debug_output
 extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
 extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4b7e639aed38da9f71478844dd993d983c8a424e..7cbf39096ec8fbbf9993e4fcd99e556037ee74ca 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -129,7 +129,9 @@ void LLGLSLShader::unload()
 }
 
 BOOL LLGLSLShader::createShader(vector<string> * attributes,
-								vector<string> * uniforms)
+								vector<string> * uniforms,
+								U32 varying_count,
+								const char** varyings)
 {
 	//reloading, reset matrix hash values
 	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
@@ -172,6 +174,13 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
 		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
 	}
 
+#ifdef GL_INTERLEAVED_ATTRIBS
+	if (varying_count > 0 && varyings)
+	{
+		glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
+	}
+#endif
+
 	// Map attributes and uniforms
 	if (success)
 	{
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7873fe3c4ee8e8d27bc0834a82f4fe5c70442d23..5c68cb46eb3b79a9811bc16a9cb146af902a6dc5 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -76,7 +76,9 @@ class LLGLSLShader
 
 	void unload();
 	BOOL createShader(std::vector<std::string> * attributes,
-						std::vector<std::string> * uniforms);
+						std::vector<std::string> * uniforms,
+						U32 varying_count = 0,
+						const char** varyings = NULL);
 	BOOL attachObject(std::string object);
 	void attachObject(GLhandleARB object);
 	void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index c04a3f6b4182d5693bf14f926ed160260c475f56..659d3ca4095a875fb2a08ced1a0e9657b05727ed 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -42,6 +42,10 @@
 //----------------------------------------------------------------------------
 const F32 MIN_TEXTURE_LIFETIME = 10.f;
 
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i);
+
 //statics
 
 U32 LLImageGL::sUniqueCount				= 0;
@@ -50,7 +54,8 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes		= 0;
 S32 LLImageGL::sBoundTextureMemoryInBytes		= 0;
 S32 LLImageGL::sCurBoundTextureMemory	= 0;
 S32 LLImageGL::sCount					= 0;
-std::list<U32> LLImageGL::sDeadTextureList;
+LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
+U32 LLImageGL::sCurTexName = 1;
 
 BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE;
 F32 LLImageGL::sLastFrameTime			= 0.f;
@@ -416,6 +421,7 @@ void LLImageGL::init(BOOL usemipmaps)
 	mTarget = GL_TEXTURE_2D;
 	mBindTarget = LLTexUnit::TT_TEXTURE;
 	mHasMipMaps = false;
+	mMipLevels = -1;
 
 	mIsResident = 0;
 
@@ -606,8 +612,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 		is_compressed = true;
 	}
 
+	
+	
+	if (mUseMipMaps)
+	{
+		//set has mip maps to true before binding image so tex parameters get set properly
+		gGL.getTexUnit(0)->unbind(mBindTarget);
+		mHasMipMaps = true;
+		mTexOptionsDirty = true;
+		setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+	}
+	else
+	{
+		mHasMipMaps = false;
+	}
+	
 	llverify(gGL.getTexUnit(0)->bind(this));
 	
+	
 	if (mUseMipMaps)
 	{
 		if (data_hasmips)
@@ -620,6 +642,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 				S32 w = getWidth(d);
 				S32 h = getHeight(d);
 				S32 gl_level = d-mCurrentDiscardLevel;
+
+				mMipLevels = llmax(mMipLevels, gl_level);
+
 				if (d > mCurrentDiscardLevel)
 				{
 					data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment
@@ -662,10 +687,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 		{
 			if (mAutoGenMips)
 			{
-				if (!gGLManager.mHasFramebufferObject)
-				{
-					glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
-				}
 				stop_glerror();
 				{
 // 					LLFastTimer t2(FTM_TEMP4);
@@ -679,6 +700,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 					S32 w = getWidth(mCurrentDiscardLevel);
 					S32 h = getHeight(mCurrentDiscardLevel);
 
+					mMipLevels = wpo2(llmax(w, h));
+
+					//use legacy mipmap generation mode
+					glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+					
 					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
 								 w, h, 
 								 mFormatPrimary, mFormatType,
@@ -694,16 +720,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						stop_glerror();
 					}
 				}
-
-				if (gGLManager.mHasFramebufferObject)
-				{
-					glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
-				}
 			}
 			else
 			{
 				// Create mips by hand
-				// about 30% faster than autogen on ATI 9800, 50% slower on nVidia 4800
 				// ~4x faster than gluBuild2DMipmaps
 				S32 width = getWidth(mCurrentDiscardLevel);
 				S32 height = getHeight(mCurrentDiscardLevel);
@@ -713,6 +733,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 				const U8* cur_mip_data = 0;
 				S32 prev_mip_size = 0;
 				S32 cur_mip_size = 0;
+				
+				mMipLevels = nummips;
+
 				for (int m=0; m<nummips; m++)
 				{
 					if (m==0)
@@ -777,10 +800,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 		{
 			llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
 		}
-		mHasMipMaps = true;
 	}
 	else
 	{
+		mMipLevels = 0;
 		S32 w = getWidth();
 		S32 h = getHeight();
 		if (is_compressed)
@@ -812,7 +835,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 			}
 
 		}
-		mHasMipMaps = false;
 	}
 	stop_glerror();
 	mGLTextureCreated = true;
@@ -1025,23 +1047,65 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
 }
 
 // static
-void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
+void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
 {
-	glGenTextures(numTextures, (GLuint*)textures);
+	bool empty = true;
+
+	dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
+	
+	if (iter != sDeadTextureList[type].end())
+	{
+		empty = iter->second.empty();
+	}
+	
+	for (S32 i = 0; i < numTextures; ++i)
+	{
+		if (!empty)
+		{
+			textures[i] = iter->second.front();
+			iter->second.pop_front();
+			empty = iter->second.empty();
+		}
+		else
+		{
+			textures[i] = sCurTexName++;
+		}
+	}
 }
 
 // static
-void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)
 {
-	for (S32 i = 0; i < numTextures; i++)
+	if (gGLManager.mInited)
 	{
-		sDeadTextureList.push_back(textures[i]);
-	}
+		if (format == 0 ||  type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
+		{ //unknown internal format or unknown number of mip levels, not safe to reuse
+			glDeleteTextures(numTextures, textures);
+		}
+		else
+		{
+			for (S32 i = 0; i < numTextures; ++i)
+			{ //remove texture from VRAM by setting its size to zero
+				for (S32 j = 0; j <= mip_levels; j++)
+				{
+					gGL.getTexUnit(0)->bindManual(type, textures[i]);
+
+					glTexImage2D(LLTexUnit::getInternalType(type), j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+				}
+
+				llassert(std::find(sDeadTextureList[type][format].begin(),
+								   sDeadTextureList[type][format].end(), textures[i]) == 
+								   sDeadTextureList[type][format].end());
 
-	if (immediate)
+				sDeadTextureList[type][format].push_back(textures[i]);
+			}	
+		}
+	}
+	
+	/*if (immediate)
 	{
 		LLImageGL::deleteDeadTextures();
-	}
+	}*/
 }
 
 // static
@@ -1166,10 +1230,11 @@ BOOL LLImageGL::createGLTexture()
 
 	if(mTexName)
 	{
-		glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
 	}
 	
-	glGenTextures(1, (GLuint*)&mTexName);
+
+	LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
 	stop_glerror();
 	if (!mTexName)
 	{
@@ -1282,7 +1347,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 	}
 	else
 	{
-		LLImageGL::generateTextures(1, &mTexName);
+		LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
 		stop_glerror();
 		{
 			llverify(gGL.getTexUnit(0)->bind(this));
@@ -1327,7 +1392,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 	{
 		sGlobalTextureMemoryInBytes -= mTextureMemory;
 
-		LLImageGL::deleteTextures(1, &old_name);
+		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
 
 		stop_glerror();
 	}
@@ -1456,7 +1521,7 @@ void LLImageGL::deleteDeadTextures()
 {
 	bool reset = false;
 
-	while (!sDeadTextureList.empty())
+	/*while (!sDeadTextureList.empty())
 	{
 		GLuint tex = sDeadTextureList.front();
 		sDeadTextureList.pop_front();
@@ -1478,7 +1543,7 @@ void LLImageGL::deleteDeadTextures()
 		
 		glDeleteTextures(1, &tex);
 		stop_glerror();
-	}
+	}*/
 
 	if (reset)
 	{
@@ -1496,7 +1561,7 @@ void LLImageGL::destroyGLTexture()
 			mTextureMemory = 0;
 		}
 		
-		LLImageGL::deleteTextures(1, &mTexName);			
+		LLImageGL::deleteTextures(mBindTarget,  mFormatInternal, mMipLevels, 1, &mTexName);			
 		mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
 		mTexName = 0;		
 		mGLTextureCreated = FALSE ;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index f34b9fa91a9302c638a953c31d53eeec2d2dc20f..e118c28c1ba2e4a9d26ad2920399f1e9e6a43f4e 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -45,8 +45,16 @@ class LLImageGL : public LLRefCount
 {
 	friend class LLTexUnit;
 public:
-	static std::list<U32> sDeadTextureList;
+	static U32 sCurTexName;
 
+	//previously used but now available texture names
+	// sDeadTextureList[<usage>][<internal format>]
+	typedef std::map<U32, std::list<U32> > dead_texturelist_t;
+	static dead_texturelist_t sDeadTextureList[LLTexUnit::TT_NONE];
+
+	// These 2 functions replace glGenTextures() and glDeleteTextures()
+	static void generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures);
+	static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate = false);
 	static void deleteDeadTextures();
 
 	// Size calculation
@@ -96,10 +104,6 @@ class LLImageGL : public LLRefCount
 	void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
 	void setAllowCompression(bool allow) { mAllowCompression = allow; }
 
-	// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() 
-	// for tracking purposes and will be deprecated in the future
-	static void generateTextures(S32 numTextures, U32 *textures);
-	static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
 	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
 
 	BOOL createGLTexture() ;
@@ -217,7 +221,8 @@ class LLImageGL : public LLRefCount
 	LLGLenum mTarget;		// Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
 	LLTexUnit::eTextureType mBindTarget;	// Normally TT_TEXTURE, sometimes something else (ex. cube maps)
 	bool mHasMipMaps;
-	
+	S32 mMipLevels;
+
 	LLGLboolean mIsResident;
 	
 	S8 mComponents;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 93bac4c779e765bc4142eb0ed525833a5b1c9d83..348c1eb1b7ab5b2076c8b75afa768d0afbc1f0a0 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -408,12 +408,14 @@ void LLTexUnit::unbind(eTextureType type)
 
 	if (mIndex < 0) return;
 
+	//always flush and activate for consistency 
+	//   some code paths assume unbind always flushes and sets the active texture
+	gGL.flush();
+	activate();
+
 	// Disabled caching of binding state.
 	if (mCurrTexType == type)
 	{
-		gGL.flush();
-
-		activate();
 		mCurrTexture = 0;
 		if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
 		{
@@ -464,11 +466,25 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
 	} 
 	else if (option >= TFO_BILINEAR)
 	{
-		glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		if (mHasMipMaps)
+		{
+			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+		}
+		else
+		{
+			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		}
 	}
 	else
 	{
-		glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		if (mHasMipMaps)
+		{
+			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+		}
+		else
+		{
+			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+		}
 	}
 
 	if (gGLManager.mHasAnisotropic)
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 780f1dc484ef082504a454416710e6432a3e43e1..99f0da330cf1d739983c186f13ef7a19550e6fae 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -55,7 +55,6 @@ bool LLRenderTarget::sUseFBO = false;
 LLRenderTarget::LLRenderTarget() :
 	mResX(0),
 	mResY(0),
-	mTex(0),
 	mFBO(0),
 	mDepth(0),
 	mStencil(0),
@@ -135,7 +134,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
 	}
 
 	U32 tex;
-	LLImageGL::generateTextures(1, &tex);
+	LLImageGL::generateTextures(mUsage, color_fmt, 1, &tex);
 	gGL.getTexUnit(0)->bindManual(mUsage, tex);
 
 	stop_glerror();
@@ -193,6 +192,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
 	}
 
 	mTex.push_back(tex);
+	mInternalFormat.push_back(color_fmt);
 
 	if (gDebugGL)
 	{ //bind and unbind to validate target
@@ -217,7 +217,7 @@ bool LLRenderTarget::allocateDepth()
 	}
 	else
 	{
-		LLImageGL::generateTextures(1, &mDepth);
+		LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
 		gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
 		
 		U32 internal_type = LLTexUnit::getInternalType(mUsage);
@@ -294,7 +294,7 @@ void LLRenderTarget::release()
 		}
 		else
 		{
-			LLImageGL::deleteTextures(1, &mDepth, true);
+			LLImageGL::deleteTextures(mUsage, 0, 0, 1, &mDepth, true);
 			stop_glerror();
 		}
 		mDepth = 0;
@@ -326,8 +326,9 @@ void LLRenderTarget::release()
 	if (mTex.size() > 0)
 	{
 		sBytesAllocated -= mResX*mResY*4*mTex.size();
-		LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
+		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
 		mTex.clear();
+		mInternalFormat.clear();
 	}
 	
 	mResX = mResY = 0;
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 2735ab21c560d2c676f8c2ce1bb28d46f859a40f..83604588401eafb354198ac2a9bfede5bfae122f 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -142,6 +142,7 @@ class LLRenderTarget
 	U32 mResX;
 	U32 mResY;
 	std::vector<U32> mTex;
+	std::vector<U32> mInternalFormat;
 	U32 mFBO;
 	U32 mDepth;
 	bool mStencil;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 5a6e6cab3e41f5388bceaa854ad552d4590fdc5c..d3b2d9fa740aaa31efd37b42508bd1e43df5eea5 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1026,6 +1026,9 @@ void LLShaderMgr::initAttribsAndUniforms()
 	mReservedUniforms.push_back("size");
 	mReservedUniforms.push_back("falloff");
 
+	mReservedUniforms.push_back("box_center");
+	mReservedUniforms.push_back("box_size");
+
 
 	mReservedUniforms.push_back("minLuminance");
 	mReservedUniforms.push_back("maxExtractAlpha");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index f792faa8f0f43e7100a974fe9e0f486ac259ca60..7a16b7c20fd6585b042476ce5d29173af3ab3567 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -97,6 +97,8 @@ class LLShaderMgr
 		LIGHT_CENTER,
 		LIGHT_SIZE,
 		LIGHT_FALLOFF,
+		BOX_CENTER,
+		BOX_SIZE,
 
 		GLOW_MIN_LUMINANCE,
 		GLOW_MAX_EXTRACT_ALPHA,
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 823c6b9dc510d2019dff2307a5b11ae8de6edba2..953546a36f351cc0b7572ed67829fa46166cb4dd 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -41,9 +41,7 @@
 #if LL_DARWIN
 #define LL_VBO_POOLING 1
 #else
-#define LL_VBO_POOLING 0
 #endif
-
 //Next Highest Power Of Two
 //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
 U32 nhpo2(U32 v)
@@ -71,6 +69,7 @@ U32 wpo2(U32 i)
 
 
 const U32 LL_VBO_BLOCK_SIZE = 2048;
+const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
 
 U32 vbo_block_size(U32 size)
 { //what block size will fit size?
@@ -83,6 +82,7 @@ U32 vbo_block_index(U32 size)
 	return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
 }
 
+const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
 
 
 //============================================================================
@@ -95,6 +95,11 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
 
 U32 LLVBOPool::sBytesPooled = 0;
 U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVBOPool::sCurGLName = 1;
+
+std::list<U32> LLVertexBuffer::sAvailableVAOName;
+U32 LLVertexBuffer::sCurVAOName = 1;
+
 U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
 U32 LLVertexBuffer::sIndexCount = 0;
 
@@ -119,69 +124,55 @@ bool LLVertexBuffer::sUseStreamDraw = true;
 bool LLVertexBuffer::sUseVAO = false;
 bool LLVertexBuffer::sPreferStreamDraw = false;
 
-const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms
 
-class LLGLSyncFence : public LLGLFence
+U32 LLVBOPool::genBuffer()
 {
-public:
-#ifdef GL_ARB_sync
-	GLsync mSync;
-#endif
-	
-	LLGLSyncFence()
-	{
-#ifdef GL_ARB_sync
-		mSync = 0;
-#endif
-	}
+	U32 ret = 0;
 
-	virtual ~LLGLSyncFence()
+	if (mGLNamePool.empty())
 	{
-#ifdef GL_ARB_sync
-		if (mSync)
-		{
-			glDeleteSync(mSync);
-		}
-#endif
+		ret = sCurGLName++;
 	}
-
-	void placeFence()
+	else
 	{
-#ifdef GL_ARB_sync
-		if (mSync)
-		{
-			glDeleteSync(mSync);
-		}
-		mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
+		ret = mGLNamePool.front();
+		mGLNamePool.pop_front();
 	}
 
-	void wait()
+	return ret;
+}
+
+void LLVBOPool::deleteBuffer(U32 name)
+{
+	if (gGLManager.mInited)
 	{
-#ifdef GL_ARB_sync
-		if (mSync)
-		{
-			while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
-			{ //track the number of times we've waited here
-				static S32 waits = 0;
-				waits++;
-			}
-		}
-#endif
-	}
+		LLVertexBuffer::unbind();
+
+		glBindBufferARB(mType, name);
+		glBufferDataARB(mType, 0, NULL, mUsage);
 
+		llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
+
+		mGLNamePool.push_back(name);
+
+		glBindBufferARB(mType, 0);
+	}
+}
 
-};
 
+LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
+: mUsage(vboUsage), mType(vboType)
+{
+	mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
+	std::fill(mMissCount.begin(), mMissCount.end(), 0);
+}
 
-volatile U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
 {
 	llassert(vbo_block_size(size) == size);
 	
 	volatile U8* ret = NULL;
 
-#if LL_VBO_POOLING
-
 	U32 i = vbo_block_index(size);
 
 	if (mFreeList.size() <= i)
@@ -189,12 +180,18 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
 		mFreeList.resize(i+1);
 	}
 
-	if (mFreeList[i].empty())
+	if (mFreeList[i].empty() || for_seed)
 	{
 		//make a new buffer
-		glGenBuffersARB(1, &name);
+		name = genBuffer();
+		
 		glBindBufferARB(mType, name);
 
+		if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
+		{ //record this miss
+			mMissCount[i]++;	
+		}
+
 		if (mType == GL_ARRAY_BUFFER_ARB)
 		{
 			LLVertexBuffer::sAllocatedBytes += size;
@@ -215,6 +212,25 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
 		}
 
 		glBindBufferARB(mType, 0);
+
+		if (for_seed)
+		{ //put into pool for future use
+			llassert(mFreeList.size() > i);
+
+			Record rec;
+			rec.mGLName = name;
+			rec.mClientData = ret;
+	
+			if (mType == GL_ARRAY_BUFFER_ARB)
+			{
+				sBytesPooled += size;
+			}
+			else
+			{
+				sIndexBytesPooled += size;
+			}
+			mFreeList[i].push_back(rec);
+		}
 	}
 	else
 	{
@@ -232,33 +248,6 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
 
 		mFreeList[i].pop_front();
 	}
-#else //no pooling
-
-	glGenBuffersARB(1, &name);
-	glBindBufferARB(mType, name);
-
-	if (mType == GL_ARRAY_BUFFER_ARB)
-	{
-		LLVertexBuffer::sAllocatedBytes += size;
-	}
-	else
-	{
-		LLVertexBuffer::sAllocatedIndexBytes += size;
-	}
-
-	if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
-	{
-		glBufferDataARB(mType, size, 0, mUsage);
-		ret = (U8*) ll_aligned_malloc_16(size);
-	}
-	else
-	{ //always use a true hint of static draw when allocating non-client-backed buffers
-		glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
-	}
-
-	glBindBufferARB(mType, 0);
-
-#endif
 
 	return ret;
 }
@@ -267,50 +256,47 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
 {
 	llassert(vbo_block_size(size) == size);
 
-#if LL_VBO_POOLING
-
-	U32 i = vbo_block_index(size);
-
-	llassert(mFreeList.size() > i);
+	deleteBuffer(name);
+	ll_aligned_free_16((U8*) buffer);
 
-	Record rec;
-	rec.mGLName = name;
-	rec.mClientData = buffer;
-	
-	if (buffer == NULL)
+	if (mType == GL_ARRAY_BUFFER_ARB)
 	{
-		glDeleteBuffersARB(1, &rec.mGLName);
+		LLVertexBuffer::sAllocatedBytes -= size;
 	}
 	else
 	{
-		if (mType == GL_ARRAY_BUFFER_ARB)
-		{
-			sBytesPooled += size;
-		}
-		else
-		{
-			sIndexBytesPooled += size;
-		}
-		mFreeList[i].push_back(rec);
+		LLVertexBuffer::sAllocatedIndexBytes -= size;
 	}
-#else //no pooling
-	glDeleteBuffersARB(1, &name);
-	ll_aligned_free_16((U8*) buffer);
+}
 
-	if (mType == GL_ARRAY_BUFFER_ARB)
+void LLVBOPool::seedPool()
+{
+	U32 dummy_name = 0;
+
+	if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
 	{
-		LLVertexBuffer::sAllocatedBytes -= size;
+		mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
 	}
-	else
+
+	for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
 	{
-		LLVertexBuffer::sAllocatedIndexBytes -= size;
+		if (mMissCount[i] > mFreeList[i].size())
+		{ 
+			U32 size = i*LL_VBO_BLOCK_SIZE;
+		
+			S32 count = mMissCount[i] - mFreeList[i].size();
+			for (U32 j = 0; j < count; ++j)
+			{
+				allocate(dummy_name, size, true);
+			}
+		}
 	}
-#endif
 }
 
+
 void LLVBOPool::cleanup()
 {
-	U32 size = 1;
+	U32 size = LL_VBO_BLOCK_SIZE;
 
 	for (U32 i = 0; i < mFreeList.size(); ++i)
 	{
@@ -320,8 +306,8 @@ void LLVBOPool::cleanup()
 		{
 			Record& r = l.front();
 
-			glDeleteBuffersARB(1, &r.mGLName);
-
+			deleteBuffer(r.mGLName);
+			
 			if (r.mClientData)
 			{
 				ll_aligned_free_16((void*) r.mClientData);
@@ -341,8 +327,11 @@ void LLVBOPool::cleanup()
 			}
 		}
 
-		size *= 2;
+		size += LL_VBO_BLOCK_SIZE;
 	}
+
+	//reset miss counts
+	std::fill(mMissCount.begin(), mMissCount.end(), 0);
 }
 
 
@@ -376,6 +365,41 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
 	GL_LINE_LOOP,
 };
 
+//static
+U32 LLVertexBuffer::getVAOName()
+{
+	U32 ret = 0;
+
+	if (!sAvailableVAOName.empty())
+	{
+		ret = sAvailableVAOName.front();
+		sAvailableVAOName.pop_front();
+	}
+	else
+	{
+#ifdef GL_ARB_vertex_array_object
+		glGenVertexArrays(1, &ret);
+#endif
+	}
+
+	return ret;		
+}
+
+//static
+void LLVertexBuffer::releaseVAOName(U32 name)
+{
+	sAvailableVAOName.push_back(name);
+}
+
+
+//static
+void LLVertexBuffer::seedPools()
+{
+	sStreamVBOPool.seedPool();
+	sDynamicVBOPool.seedPool();
+	sStreamIBOPool.seedPool();
+	sDynamicIBOPool.seedPool();
+}
 
 //static
 void LLVertexBuffer::setupClientArrays(U32 data_mask)
@@ -985,7 +1009,7 @@ LLVertexBuffer::~LLVertexBuffer()
 	if (mGLArray)
 	{
 #if GL_ARB_vertex_array_object
-		glDeleteVertexArrays(1, &mGLArray);
+		releaseVAOName(mGLArray);
 #endif
 	}
 
@@ -1211,10 +1235,10 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
 
 	llassert(nverts >= 0);
 
-	if (nverts >= 65535)
+	if (nverts > 65536)
 	{
 		llwarns << "Vertex buffer overflow!" << llendl;
-		nverts = 65535;
+		nverts = 65536;
 	}
 
 	U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
@@ -1270,7 +1294,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
 		if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
 		{
 #if GL_ARB_vertex_array_object
-			glGenVertexArrays(1, &mGLArray);
+			mGLArray = getVAOName();
 #endif
 			setupVertexArray();
 		}
@@ -2140,6 +2164,16 @@ void LLVertexBuffer::flush()
 	}
 }
 
+// bind for transform feedback (quick 'n dirty)
+void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
+{
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+	U32 offset = mOffsets[type] + sTypeSize[type]*index;
+	U32 size= (sTypeSize[type]*count);
+	glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
+#endif
+}
+
 // Set for rendering
 void LLVertexBuffer::setBuffer(U32 data_mask)
 {
@@ -2291,10 +2325,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
 	stop_glerror();
 	volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
 
-	/*if ((data_mask & mTypeMask) != data_mask)
+	if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
 	{
 		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
-	}*/
+	}
 
 	if (LLGLSLShader::sNoFixedFunction)
 	{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 7477dec3adaab878c054cae88abbfe38516128b2..11fa4ab6a0da3b7862298801072572cf9dd0b3dd 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -57,23 +57,28 @@ class LLVBOPool
 	static U32 sBytesPooled;
 	static U32 sIndexBytesPooled;
 	
-	LLVBOPool(U32 vboUsage, U32 vboType)
-		: mUsage(vboUsage)
-		, mType(vboType)
-	{}
+	static U32 sCurGLName;
 
+	LLVBOPool(U32 vboUsage, U32 vboType);
+		
 	const U32 mUsage;
 	const U32 mType;
 
 	//size MUST be a power of 2
-	volatile U8* allocate(U32& name, U32 size);
+	volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
 	
 	//size MUST be the size provided to allocate that returned the given name
 	void release(U32 name, volatile U8* buffer, U32 size);
 	
+	//batch allocate buffers to be provided to the application on demand
+	void seedPool();
+
 	//destroy all records in mFreeList
 	void cleanup();
 
+	U32 genBuffer();
+	void deleteBuffer(U32 name);
+
 	class Record
 	{
 	public:
@@ -81,17 +86,15 @@ class LLVBOPool
 		volatile U8* mClientData;
 	};
 
+	std::list<U32> mGLNamePool;
+
 	typedef std::list<Record> record_list_t;
 	std::vector<record_list_t> mFreeList;
-};
+	std::vector<U32> mMissCount;
 
-class LLGLFence
-{
-public:
-	virtual void placeFence() = 0;
-	virtual void wait() = 0;
 };
 
+
 //============================================================================
 // base class 
 class LLPrivateMemoryPool;
@@ -125,13 +128,22 @@ class LLVertexBuffer : public LLRefCount
 	static LLVBOPool sStreamIBOPool;
 	static LLVBOPool sDynamicIBOPool;
 
+	static std::list<U32> sAvailableVAOName;
+	static U32 sCurVAOName;
+
 	static bool	sUseStreamDraw;
 	static bool sUseVAO;
 	static bool	sPreferStreamDraw;
 
+	static void seedPools();
+
+	static U32 getVAOName();
+	static void releaseVAOName(U32 name);
+
 	static void initClass(bool use_vbo, bool no_vbo_mapping);
 	static void cleanupClass();
 	static void setupClientArrays(U32 data_mask);
+	static void pushPositions(U32 mode, const LLVector4a* pos, U32 count);
 	static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
 	static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
 
@@ -208,7 +220,6 @@ class LLVertexBuffer : public LLRefCount
 	void 	destroyGLIndices();
 	void	updateNumVerts(S32 nverts);
 	void	updateNumIndices(S32 nindices); 
-	bool	useVBOs() const;
 	void	unmapBuffer();
 		
 public:
@@ -218,6 +229,8 @@ class LLVertexBuffer : public LLRefCount
 	volatile U8*		mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
 	volatile U8*		mapIndexBuffer(S32 index, S32 count, bool map_range);
 
+	void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
+
 	// set for rendering
 	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0
 	void flush(); //flush pending data to GL memory
@@ -240,12 +253,14 @@ class LLVertexBuffer : public LLRefCount
 	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+	bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
 	
 
+	bool useVBOs() const;
 	bool isEmpty() const					{ return mEmpty; }
 	bool isLocked() const					{ return mVertexLocked || mIndexLocked; }
 	S32 getNumVerts() const					{ return mNumVerts; }
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 20c3456a56a816ac3fda9c3edf0eb17fdefc033d..cca4ca3981097173483121f310e906354184d1f6 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -23,6 +23,7 @@ include_directories(
     ${LLWINDOW_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
+    ${LIBS_PREBUILD_DIR}/include/hunspell
     )
 
 set(llui_SOURCE_FILES
@@ -84,6 +85,7 @@ set(llui_SOURCE_FILES
     llsearcheditor.cpp
     llslider.cpp
     llsliderctrl.cpp
+    llspellcheck.cpp
     llspinctrl.cpp
     llstatbar.cpp
     llstatgraph.cpp
@@ -191,6 +193,8 @@ set(llui_HEADER_FILES
     llscrolllistitem.h
     llsliderctrl.h
     llslider.h
+    llspellcheck.h
+    llspellcheckmenuhandler.h
     llspinctrl.h
     llstatbar.h
     llstatgraph.h
@@ -260,6 +264,7 @@ target_link_libraries(llui
     ${LLXUIXML_LIBRARIES}
     ${LLXML_LIBRARIES}
     ${LLMATH_LIBRARIES}
+    ${HUNSPELL_LIBRARY}
     ${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
     )
 
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index d0fbf4b91370d6c7f46c2e3addb9306cca2cbaa5..48d49af58810e4e4eccc3a73072ddd2821a431ae 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -45,6 +45,7 @@
 #include "llkeyboard.h"
 #include "llrect.h"
 #include "llresmgr.h"
+#include "llspellcheck.h"
 #include "llstring.h"
 #include "llwindow.h"
 #include "llui.h"
@@ -65,6 +66,7 @@ const S32	SCROLL_INCREMENT_ADD = 0;	// make space for typing
 const S32   SCROLL_INCREMENT_DEL = 4;	// make space for baskspacing
 const F32   AUTO_SCROLL_TIME = 0.05f;
 const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click. *TODO: make this equal to the double click interval?
+const F32	SPELLCHECK_DELAY = 0.5f;	// delay between the last keypress and spell checking the word the cursor is on
 
 const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET
 
@@ -88,6 +90,7 @@ LLLineEditor::Params::Params()
 	background_image_focused("background_image_focused"),
 	select_on_focus("select_on_focus", false),
 	revert_on_esc("revert_on_esc", true),
+	spellcheck("spellcheck", false),
 	commit_on_focus_lost("commit_on_focus_lost", true),
 	ignore_tab("ignore_tab", true),
 	is_password("is_password", false),
@@ -134,6 +137,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mIgnoreArrowKeys( FALSE ),
 	mIgnoreTab( p.ignore_tab ),
 	mDrawAsterixes( p.is_password ),
+	mSpellCheck( p.spellcheck ),
+	mSpellCheckStart(-1),
+	mSpellCheckEnd(-1),
 	mSelectAllonFocusReceived( p.select_on_focus ),
 	mSelectAllonCommit( TRUE ),
 	mPassDelete(FALSE),
@@ -151,7 +157,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mHighlightColor(p.highlight_color()),
 	mPreeditBgColor(p.preedit_bg_color()),
 	mGLFont(p.font),
-	mContextMenuHandle()
+	mContextMenuHandle(),
+	mAutoreplaceCallback()
 {
 	llassert( mMaxLengthBytes > 0 );
 
@@ -177,6 +184,12 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	updateTextPadding();
 	setCursor(mText.length());
 
+	if (mSpellCheck)
+	{
+		LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLLineEditor::onSpellCheckSettingsChange, this));
+	}
+	mSpellCheckTimer.reset();
+
 	setPrevalidateInput(p.prevalidate_input_callback());
 	setPrevalidate(p.prevalidate_callback());
 
@@ -195,7 +208,6 @@ LLLineEditor::~LLLineEditor()
 	gFocusMgr.releaseFocusIfNeeded( this );
 }
 
-
 void LLLineEditor::onFocusReceived()
 {
 	gEditMenuHandler = this;
@@ -519,6 +531,99 @@ void LLLineEditor::selectAll()
 	updatePrimary();
 }
 
+bool LLLineEditor::getSpellCheck() const
+{
+	return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck);
+}
+
+const std::string& LLLineEditor::getSuggestion(U32 index) const
+{
+	return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null;
+}
+
+U32 LLLineEditor::getSuggestionCount() const
+{
+	return mSuggestionList.size();
+}
+
+void LLLineEditor::replaceWithSuggestion(U32 index)
+{
+	for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+	{
+		if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
+		{
+			deselect();
+
+			// Delete the misspelled word
+			mText.erase(it->first, it->second - it->first);
+
+			// Insert the suggestion in its place
+			LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
+			mText.insert(it->first, suggestion);
+			setCursor(it->first + (S32)suggestion.length());
+
+			break;
+		}
+	}
+	mSpellCheckStart = mSpellCheckEnd = -1;
+}
+
+void LLLineEditor::addToDictionary()
+{
+	if (canAddToDictionary())
+	{
+		LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos));
+	}
+}
+
+bool LLLineEditor::canAddToDictionary() const
+{
+	return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+void LLLineEditor::addToIgnore()
+{
+	if (canAddToIgnore())
+	{
+		LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos));
+	}
+}
+
+bool LLLineEditor::canAddToIgnore() const
+{
+	return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+std::string LLLineEditor::getMisspelledWord(U32 pos) const
+{
+	for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+	{
+		if ( (it->first <= pos) && (it->second >= pos) )
+		{
+			return wstring_to_utf8str(mText.getWString().substr(it->first, it->second - it->first));
+		}
+	}
+	return LLStringUtil::null;
+}
+
+bool LLLineEditor::isMisspelledWord(U32 pos) const
+{
+	for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+	{
+		if ( (it->first <= pos) && (it->second >= pos) )
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+void LLLineEditor::onSpellCheckSettingsChange()
+{
+	// Recheck the spelling on every change
+	mMisspellRanges.clear();
+	mSpellCheckStart = mSpellCheckEnd = -1;
+}
 
 BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
@@ -866,6 +971,12 @@ void LLLineEditor::addChar(const llwchar uni_char)
 		LLUI::reportBadKeystroke();
 	}
 
+	if (!mReadOnly && mAutoreplaceCallback != NULL)
+	{
+		// call callback
+		mAutoreplaceCallback(mText, mCursorPos);
+	}
+
 	getWindow()->hideCursorUntilMouseMove();
 }
 
@@ -1058,9 +1169,8 @@ void LLLineEditor::cut()
 			LLUI::reportBadKeystroke();
 		}
 		else
-		if( mKeystrokeCallback )
 		{
-			mKeystrokeCallback( this );
+			onKeystroke();
 		}
 	}
 }
@@ -1187,9 +1297,8 @@ void LLLineEditor::pasteHelper(bool is_primary)
 				LLUI::reportBadKeystroke();
 			}
 			else
-			if( mKeystrokeCallback )
 			{
-				mKeystrokeCallback( this );
+				onKeystroke();
 			}
 		}
 	}
@@ -1442,9 +1551,10 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
 			// Notify owner if requested
 			if (!need_to_rollback && handled)
 			{
-				if (mKeystrokeCallback)
+				onKeystroke();
+				if ( (!selection_modified) && (KEY_BACKSPACE == key) )
 				{
-					mKeystrokeCallback(this);
+					mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
 				}
 			}
 		}
@@ -1497,12 +1607,11 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
 		// Notify owner if requested
 		if( !need_to_rollback && handled )
 		{
-			if( mKeystrokeCallback )
-			{
-				// HACK! The only usage of this callback doesn't do anything with the character.
-				// We'll have to do something about this if something ever changes! - Doug
-				mKeystrokeCallback( this );
-			}
+			// HACK! The only usage of this callback doesn't do anything with the character.
+			// We'll have to do something about this if something ever changes! - Doug
+			onKeystroke();
+
+			mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
 		}
 	}
 	return handled;
@@ -1531,9 +1640,7 @@ void LLLineEditor::doDelete()
 
 			if (!prevalidateInput(text_to_delete))
 			{
-				if( mKeystrokeCallback )
-					mKeystrokeCallback( this );
-
+				onKeystroke();
 				return;
 			}
 			setCursor(getCursor() + 1);
@@ -1549,10 +1656,9 @@ void LLLineEditor::doDelete()
 		}
 		else
 		{
-			if( mKeystrokeCallback )
-			{
-				mKeystrokeCallback( this );
-			}
+			onKeystroke();
+
+			mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
 		}
 	}
 }
@@ -1624,6 +1730,10 @@ void LLLineEditor::draw()
 	background.stretch( -mBorderThickness );
 
 	S32 lineeditor_v_pad = (background.getHeight() - mGLFont->getLineHeight()) / 2;
+	if (mSpellCheck)
+	{
+		lineeditor_v_pad += 1;
+	}
 
 	drawBackground();
 	
@@ -1698,14 +1808,14 @@ void LLLineEditor::draw()
 	{
 		S32 select_left;
 		S32 select_right;
-		if( mSelectionStart < getCursor() )
+		if (mSelectionStart < mSelectionEnd)
 		{
 			select_left = mSelectionStart;
-			select_right = getCursor();
+			select_right = mSelectionEnd;
 		}
 		else
 		{
-			select_left = getCursor();
+			select_left = mSelectionEnd;
 			select_right = mSelectionStart;
 		}
 		
@@ -1749,7 +1859,7 @@ void LLLineEditor::draw()
 		if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
 		{
 			// unselected, right side
-			mGLFont->render( 
+			rendered_text += mGLFont->render( 
 				mText, mScrollHPos + rendered_text,
 				rendered_pixels_right, text_bottom,
 				text_color,
@@ -1763,7 +1873,7 @@ void LLLineEditor::draw()
 	}
 	else
 	{
-		mGLFont->render( 
+		rendered_text = mGLFont->render( 
 			mText, mScrollHPos, 
 			rendered_pixels_right, text_bottom,
 			text_color,
@@ -1778,6 +1888,101 @@ void LLLineEditor::draw()
 	mBorder->setVisible(FALSE); // no more programmatic art.
 #endif
 
+	if ( (getSpellCheck()) && (mText.length() > 2) )
+	{
+		// Calculate start and end indices for the first and last visible word
+		U32 start = prevWordPos(mScrollHPos), end = nextWordPos(mScrollHPos + rendered_text);
+
+		if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
+		{
+			const LLWString& text = mText.getWString().substr(start, end);
+
+			// Find the start of the first word
+			U32 word_start = 0, word_end = 0;
+			while ( (word_start < text.length()) && (!LLStringOps::isAlpha(text[word_start])) )
+			{
+				word_start++;
+			}
+
+			// Iterate over all words in the text block and check them one by one
+			mMisspellRanges.clear();
+			while (word_start < text.length())
+			{
+				// Find the end of the current word (special case handling for "'" when it's used as a contraction)
+				word_end = word_start + 1;
+				while ( (word_end < text.length()) && 
+					    ((LLWStringUtil::isPartOfWord(text[word_end])) ||
+						 ((L'\'' == text[word_end]) && (word_end + 1 < text.length()) &&
+						  (LLStringOps::isAlnum(text[word_end - 1])) && (LLStringOps::isAlnum(text[word_end + 1])))) )
+				{
+					word_end++;
+				}
+				if (word_end > text.length())
+				{
+					break;
+				}
+
+				// Don't process words shorter than 3 characters
+				std::string word = wstring_to_utf8str(text.substr(word_start, word_end - word_start));
+				if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+				{
+					mMisspellRanges.push_back(std::pair<U32, U32>(start + word_start, start + word_end));
+				}
+
+				// Find the start of the next word
+				word_start = word_end + 1;
+				while ( (word_start < text.length()) && (!LLWStringUtil::isPartOfWord(text[word_start])) )
+				{
+					word_start++;
+				}
+			}
+
+			mSpellCheckStart = start;
+			mSpellCheckEnd = end;
+		}
+
+		// Draw squiggly lines under any (visible) misspelled words
+		for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+		{
+			// Skip over words that aren't (partially) visible
+			if ( ((it->first < start) && (it->second < start)) || (it->first > end) )
+			{
+				continue;
+			}
+
+			// Skip the current word if the user is still busy editing it
+			if ( (!mSpellCheckTimer.hasExpired()) && (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
+			{
+ 				continue;
+			}
+
+			S32 pxWidth = getRect().getWidth();
+			S32 pxStart = findPixelNearestPos(it->first - getCursor());
+			if (pxStart > pxWidth)
+			{
+				continue;
+			}
+			S32 pxEnd = findPixelNearestPos(it->second - getCursor());
+			if (pxEnd > pxWidth)
+			{
+				pxEnd = pxWidth;
+			}
+
+			S32 pxBottom = (S32)(text_bottom + mGLFont->getDescenderHeight());
+
+			gGL.color4ub(255, 0, 0, 200);
+			while (pxStart + 1 < pxEnd)
+			{
+				gl_line_2d(pxStart, pxBottom, pxStart + 2, pxBottom - 2);
+				if (pxStart + 3 < pxEnd)
+				{
+					gl_line_2d(pxStart + 2, pxBottom - 3, pxStart + 4, pxBottom - 1);
+				}
+				pxStart += 4;
+			}
+		}
+	}
+
 	// If we're editing...
 	if( hasFocus())
 	{
@@ -2109,6 +2314,15 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
 	mSelectAllonFocusReceived = b;
 }
 
+void LLLineEditor::onKeystroke()
+{
+	if (mKeystrokeCallback)
+	{
+		mKeystrokeCallback(this);
+	}
+
+	mSpellCheckStart = mSpellCheckEnd = -1;
+}
 
 void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
 {
@@ -2231,10 +2445,9 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
 
 	// Update of the preedit should be caused by some key strokes.
 	mKeystrokeTimer.reset();
-	if( mKeystrokeCallback )
-	{
-		mKeystrokeCallback( this );
-	}
+	onKeystroke();
+
+	mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
 }
 
 BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -2386,7 +2599,38 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
 
 		S32 screen_x, screen_y;
 		localPointToScreen(x, y, &screen_x, &screen_y);
-		menu->show(screen_x, screen_y);
+
+		setCursorAtLocalPos(x);
+		if (hasSelection())
+		{
+			if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) )
+			{
+				deselect();
+			}
+			else
+			{
+				setCursor(llmax(mSelectionStart, mSelectionEnd));
+			}
+		}
+
+		bool use_spellcheck = getSpellCheck(), is_misspelled = false;
+		if (use_spellcheck)
+		{
+			mSuggestionList.clear();
+
+			// If the cursor is on a misspelled word, retrieve suggestions for it
+			std::string misspelled_word = getMisspelledWord(mCursorPos);
+			if ((is_misspelled = !misspelled_word.empty()) == true)
+			{
+				LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList);
+			}
+		}
+
+		menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
+		menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
+		menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
+		menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
+		menu->show(screen_x, screen_y, this);
 	}
 }
 
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 2518dbe3c73cea0ff101500a39627265cc47b7f5..71dd53f60838a880fa47a1230017d849492a18eb 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -40,6 +40,7 @@
 #include "llframetimer.h"
 
 #include "lleditmenuhandler.h"
+#include "llspellcheckmenuhandler.h"
 #include "lluictrl.h"
 #include "lluiimage.h"
 #include "lluistring.h"
@@ -54,7 +55,7 @@ class LLButton;
 class LLContextMenu;
 
 class LLLineEditor
-: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor
+: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor, public LLSpellCheckMenuHandler
 {
 public:
 
@@ -86,6 +87,7 @@ class LLLineEditor
 
 		Optional<bool>					select_on_focus,
 										revert_on_esc,
+										spellcheck,
 										commit_on_focus_lost,
 										ignore_tab,
 										is_password;
@@ -146,6 +148,24 @@ class LLLineEditor
 	virtual void	deselect();
 	virtual BOOL	canDeselect() const;
 
+	// LLSpellCheckMenuHandler overrides
+	/*virtual*/ bool	getSpellCheck() const;
+
+	/*virtual*/ const std::string& getSuggestion(U32 index) const;
+	/*virtual*/ U32		getSuggestionCount() const;
+	/*virtual*/ void	replaceWithSuggestion(U32 index);
+
+	/*virtual*/ void	addToDictionary();
+	/*virtual*/ bool	canAddToDictionary() const;
+
+	/*virtual*/ void	addToIgnore();
+	/*virtual*/ bool	canAddToIgnore() const;
+
+	// Spell checking helper functions
+	std::string			getMisspelledWord(U32 pos) const;
+	bool				isMisspelledWord(U32 pos) const;
+	void				onSpellCheckSettingsChange();
+
 	// view overrides
 	virtual void	draw();
 	virtual void	reshape(S32 width,S32 height,BOOL called_from_parent=TRUE);
@@ -169,6 +189,9 @@ class LLLineEditor
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 
+	typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
+	autoreplace_callback_t mAutoreplaceCallback;
+	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
 	void			setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
 	const std::string& 	getLabel()	{ return mLabel.getString(); }
 
@@ -223,6 +246,7 @@ class LLLineEditor
 	void			setSelectAllonFocusReceived(BOOL b);
 	void			setSelectAllonCommit(BOOL b) { mSelectAllonCommit = b; }
 	
+	void			onKeystroke();
 	typedef boost::function<void (LLLineEditor* caller, void* user_data)> callback_t;
 	void			setKeystrokeCallback(callback_t callback, void* user_data);
 
@@ -322,6 +346,13 @@ class LLLineEditor
 	S32			mLastSelectionStart;
 	S32			mLastSelectionEnd;
 
+	bool		mSpellCheck;
+	S32			mSpellCheckStart;
+	S32			mSpellCheckEnd;
+	LLTimer		mSpellCheckTimer;
+	std::list<std::pair<U32, U32> > mMisspellRanges;
+	std::vector<std::string>		mSuggestionList;
+
 	LLTextValidate::validate_func_t mPrevalidateFunc;
 	LLTextValidate::validate_func_t mPrevalidateInputFunc;
 
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ff6928ffda10b9ebf2188483c286338a736d97ba..efb9848a909593c0a2e68fa05744d5371bc6c2d4 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3854,7 +3854,7 @@ void LLContextMenu::setVisible(BOOL visible)
 }
 
 // Takes cursor position in screen space?
-void LLContextMenu::show(S32 x, S32 y)
+void LLContextMenu::show(S32 x, S32 y, LLView* spawning_view)
 {
 	if (getChildList()->empty())
 	{
@@ -3908,6 +3908,14 @@ void LLContextMenu::show(S32 x, S32 y)
 	setRect(rect);
 	arrange();
 
+	if (spawning_view)
+	{
+		mSpawningViewHandle = spawning_view->getHandle();
+	}
+	else
+	{
+		mSpawningViewHandle.markDead();
+	}
 	LLView::setVisible(TRUE);
 }
 
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 36f3ba34b9b5e45c3271563e0efc7224acbb86fe..67b3e1fbe669587bc41ef47fb58cf9a262395dc1 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -670,7 +670,7 @@ class LLContextMenu
 	
 	virtual void	draw				();
 	
-	virtual void	show				(S32 x, S32 y);
+	virtual void	show				(S32 x, S32 y, LLView* spawning_view = NULL);
 	virtual void	hide				();
 
 	virtual BOOL	handleHover			( S32 x, S32 y, MASK mask );
@@ -683,10 +683,14 @@ class LLContextMenu
 
 			LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
 
+			LLView*	getSpawningView() const		{ return mSpawningViewHandle.get(); }
+			void	setSpawningView(LLHandle<LLView> spawning_view) { mSpawningViewHandle = spawning_view; }
+
 protected:
 	BOOL						mHoveredAnyItem;
 	LLMenuItemGL*				mHoverItem;
 	LLRootHandle<LLContextMenu>	mHandle;
+	LLHandle<LLView>			mSpawningViewHandle;
 };
 
 
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 9b7e30bb048733ce8e8b193dc40918a1571f1c36..2fd187a526803d1c62a01243c597620e0b2ee1e3 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -389,12 +389,11 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
 		{
 			*show_h_scrollbar = TRUE;
 			*visible_height -= scrollbar_size;
-
+			// Note: Do *not* recompute *show_v_scrollbar here because with
 			// The view inside the scroll container should not be extended
 			// to container's full height to ensure the correct computation
 			// of *show_v_scrollbar after subtracting horizontal scrollbar_size.
 
-			// Must retest now that visible_height has changed
 			if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) )
 			{
 				*show_v_scrollbar = TRUE;
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a189375fbea58d3c2f9a4469c09c8bf0c7bccbf9
--- /dev/null
+++ b/indra/llui/llspellcheck.cpp
@@ -0,0 +1,505 @@
+/** 
+ * @file llspellcheck.cpp
+ * @brief Spell checking functionality
+ *
+ * $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"
+
+#include "lldir.h"
+#include "llsdserialize.h"
+
+#include "llspellcheck.h"
+#if LL_WINDOWS
+	#include <hunspell/hunspelldll.h>
+	#pragma comment(lib, "libhunspell.lib")
+#else
+	#include <hunspell/hunspell.hxx>
+#endif
+
+static const std::string DICT_DIR = "dictionaries";
+static const std::string DICT_FILE_CUSTOM = "user_custom.dic";
+static const std::string DICT_FILE_IGNORE = "user_ignore.dic";
+
+static const std::string DICT_FILE_MAIN = "dictionaries.xml";
+static const std::string DICT_FILE_USER = "user_dictionaries.xml";
+
+LLSD LLSpellChecker::sDictMap;
+LLSpellChecker::settings_change_signal_t LLSpellChecker::sSettingsChangeSignal;
+
+LLSpellChecker::LLSpellChecker()
+	: mHunspell(NULL)
+{
+	// Load initial dictionary information
+	refreshDictionaryMap();
+}
+
+LLSpellChecker::~LLSpellChecker()
+{
+	delete mHunspell;
+}
+
+bool LLSpellChecker::checkSpelling(const std::string& word) const
+{
+	if ( (!mHunspell) || (word.length() < 3) || (0 != mHunspell->spell(word.c_str())) )
+	{
+		return true;
+	}
+	if (mIgnoreList.size() > 0)
+	{
+		std::string word_lower(word);
+		LLStringUtil::toLower(word_lower);
+		return (mIgnoreList.end() != std::find(mIgnoreList.begin(), mIgnoreList.end(), word_lower));
+	}
+	return false;
+}
+
+S32 LLSpellChecker::getSuggestions(const std::string& word, std::vector<std::string>& suggestions) const
+{
+	suggestions.clear();
+	if ( (!mHunspell) || (word.length() < 3) )
+	{
+		return 0;
+	}
+
+	char** suggestion_list; int suggestion_cnt = 0;
+	if ( (suggestion_cnt = mHunspell->suggest(&suggestion_list, word.c_str())) != 0 )
+	{
+		for (int suggestion_index = 0; suggestion_index < suggestion_cnt; suggestion_index++)
+		{
+			suggestions.push_back(suggestion_list[suggestion_index]);
+		}
+		mHunspell->free_list(&suggestion_list, suggestion_cnt);	
+	}
+	return suggestions.size();
+}
+
+// static
+const LLSD LLSpellChecker::getDictionaryData(const std::string& dict_language)
+{
+	for (LLSD::array_const_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
+	{
+		const LLSD& dict_entry = *it;
+		if (dict_language == dict_entry["language"].asString())
+		{
+			return dict_entry;
+		}
+	}
+	return LLSD();
+}
+
+// static
+bool LLSpellChecker::hasDictionary(const std::string& dict_language, bool check_installed)
+{
+	const LLSD dict_info = getDictionaryData(dict_language);
+	return dict_info.has("language") && ( (!check_installed) || (dict_info["installed"].asBoolean()) );
+}
+
+// static
+void LLSpellChecker::setDictionaryData(const LLSD& dict_info)
+{
+	const std::string dict_language = dict_info["language"].asString();
+	if (dict_language.empty())
+	{
+		return;
+	}
+
+	for (LLSD::array_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
+	{
+		LLSD& dict_entry = *it;
+		if (dict_language == dict_entry["language"].asString())
+		{
+			dict_entry = dict_info;
+			return;
+		}
+	}
+	sDictMap.append(dict_info);
+	return;
+}
+
+// static
+void LLSpellChecker::refreshDictionaryMap()
+{
+	const std::string app_path = getDictionaryAppPath();
+	const std::string user_path = getDictionaryUserPath();
+
+	// 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()) )
+	{
+		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()) )
+		{
+			return;
+		}
+	}
+
+	// Load user installed dictionary information
+	llifstream custom_file(user_path + DICT_FILE_USER, std::ios::binary);
+	if (custom_file.is_open())
+	{
+		LLSD custom_dict_map;
+		LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file);
+		for (LLSD::array_iterator it = custom_dict_map.beginArray(); it != custom_dict_map.endArray(); ++it)
+		{
+			LLSD& dict_info = *it;
+			dict_info["user_installed"] = true;
+			setDictionaryData(dict_info);
+		}
+		custom_file.close();
+	}
+
+	// Look for installed dictionaries
+	std::string tmp_app_path, tmp_user_path;
+	for (LLSD::array_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
+	{
+		LLSD& sdDict = *it;
+		tmp_app_path = (sdDict.has("name")) ? app_path + sdDict["name"].asString() : LLStringUtil::null;
+		tmp_user_path = (sdDict.has("name")) ? user_path + sdDict["name"].asString() : LLStringUtil::null;
+		sdDict["installed"] = 
+			(!tmp_app_path.empty()) && ((gDirUtilp->fileExists(tmp_user_path + ".dic")) || (gDirUtilp->fileExists(tmp_app_path + ".dic")));
+	}
+
+	sSettingsChangeSignal();
+}
+
+void LLSpellChecker::addToCustomDictionary(const std::string& word)
+{
+	if (mHunspell)
+	{
+		mHunspell->add(word.c_str());
+	}
+	addToDictFile(getDictionaryUserPath() + DICT_FILE_CUSTOM, word);
+	sSettingsChangeSignal();
+}
+
+void LLSpellChecker::addToIgnoreList(const std::string& word)
+{
+	std::string word_lower(word);
+	LLStringUtil::toLower(word_lower);
+	if (mIgnoreList.end() == std::find(mIgnoreList.begin(), mIgnoreList.end(), word_lower))
+	{
+		mIgnoreList.push_back(word_lower);
+		addToDictFile(getDictionaryUserPath() + DICT_FILE_IGNORE, word_lower);
+		sSettingsChangeSignal();
+	}
+}
+
+void LLSpellChecker::addToDictFile(const std::string& dict_path, const std::string& word)
+{
+	std::vector<std::string> word_list;
+
+	if (gDirUtilp->fileExists(dict_path))
+	{
+		llifstream file_in(dict_path, std::ios::in);
+		if (file_in.is_open())
+		{
+			std::string word; int line_num = 0;
+			while (getline(file_in, word))
+			{
+				// Skip over the first line since that's just a line count
+				if (0 != line_num)
+				{
+					word_list.push_back(word);
+				}
+				line_num++;
+			}
+		}
+		else
+		{
+			// TODO: show error message?
+			return;
+		}
+	}
+
+	word_list.push_back(word);
+
+	llofstream file_out(dict_path, std::ios::out | std::ios::trunc);	
+	if (file_out.is_open())
+	{
+		file_out << word_list.size() << std::endl;
+		for (std::vector<std::string>::const_iterator itWord = word_list.begin(); itWord != word_list.end(); ++itWord)
+		{
+			file_out << *itWord << std::endl;
+		}
+		file_out.close();
+	}
+}
+
+bool LLSpellChecker::isActiveDictionary(const std::string& dict_language) const
+{
+	return
+		(mDictLanguage == dict_language) || 
+		(mDictSecondary.end() != std::find(mDictSecondary.begin(), mDictSecondary.end(), dict_language));
+}
+
+void LLSpellChecker::setSecondaryDictionaries(dict_list_t dict_list)
+{
+	if (!getUseSpellCheck())
+	{
+		return;
+	}
+
+	// Check if we're only adding secondary dictionaries, or removing them
+	dict_list_t dict_add(llmax(dict_list.size(), mDictSecondary.size())), dict_rem(llmax(dict_list.size(), mDictSecondary.size()));
+	dict_list.sort();
+	mDictSecondary.sort();
+	dict_list_t::iterator end_added = std::set_difference(dict_list.begin(), dict_list.end(), mDictSecondary.begin(), mDictSecondary.end(), dict_add.begin());
+	dict_list_t::iterator end_removed = std::set_difference(mDictSecondary.begin(), mDictSecondary.end(), dict_list.begin(), dict_list.end(), dict_rem.begin());
+
+	if (end_removed != dict_rem.begin())		// We can't remove secondary dictionaries so we need to recreate the Hunspell instance
+	{
+		mDictSecondary = dict_list;
+
+		std::string dict_language = mDictLanguage;
+		initHunspell(dict_language);
+	}
+	else if (end_added != dict_add.begin())		// Add the new secondary dictionaries one by one
+	{
+		const std::string app_path = getDictionaryAppPath();
+		const std::string user_path = getDictionaryUserPath();
+		for (dict_list_t::const_iterator it_added = dict_add.begin(); it_added != end_added; ++it_added)
+		{
+			const LLSD dict_entry = getDictionaryData(*it_added);
+			if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) )
+			{
+				continue;
+			}
+
+			const std::string strFileDic = dict_entry["name"].asString() + ".dic";
+			if (gDirUtilp->fileExists(user_path + strFileDic))
+			{
+				mHunspell->add_dic((user_path + strFileDic).c_str());
+			}
+			else if (gDirUtilp->fileExists(app_path + strFileDic))
+			{
+				mHunspell->add_dic((app_path + strFileDic).c_str());
+			}
+		}
+		mDictSecondary = dict_list;
+		sSettingsChangeSignal();
+	}
+}
+
+void LLSpellChecker::initHunspell(const std::string& dict_language)
+{
+	if (mHunspell)
+	{
+		delete mHunspell;
+		mHunspell = NULL;
+		mDictLanguage.clear();
+		mDictFile.clear();
+		mIgnoreList.clear();
+	}
+
+	const LLSD dict_entry = (!dict_language.empty()) ? getDictionaryData(dict_language) : LLSD();
+	if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) || (!dict_entry["is_primary"].asBoolean()))
+	{
+		sSettingsChangeSignal();
+		return;
+	}
+
+	const std::string app_path = getDictionaryAppPath();
+	const std::string user_path = getDictionaryUserPath();
+	if (dict_entry.has("name"))
+	{
+		const std::string filename_aff = dict_entry["name"].asString() + ".aff";
+		const std::string filename_dic = dict_entry["name"].asString() + ".dic";
+		if ( (gDirUtilp->fileExists(user_path + filename_aff)) && (gDirUtilp->fileExists(user_path + filename_dic)) )
+		{
+			mHunspell = new Hunspell((user_path + filename_aff).c_str(), (user_path + filename_dic).c_str());
+		}
+		else if ( (gDirUtilp->fileExists(app_path + filename_aff)) && (gDirUtilp->fileExists(app_path + filename_dic)) )
+		{
+			mHunspell = new Hunspell((app_path + filename_aff).c_str(), (app_path + filename_dic).c_str());
+		}
+		if (!mHunspell)
+		{
+			return;
+		}
+
+		mDictLanguage = dict_language;
+		mDictFile = dict_entry["name"].asString();
+
+		if (gDirUtilp->fileExists(user_path + DICT_FILE_CUSTOM))
+		{
+			mHunspell->add_dic((user_path + DICT_FILE_CUSTOM).c_str());
+		}
+
+		if (gDirUtilp->fileExists(user_path + DICT_FILE_IGNORE))
+		{
+			llifstream file_in(user_path + DICT_FILE_IGNORE, std::ios::in);
+			if (file_in.is_open())
+			{
+				std::string word; int idxLine = 0;
+				while (getline(file_in, word))
+				{
+					// Skip over the first line since that's just a line count
+					if (0 != idxLine)
+					{
+						LLStringUtil::toLower(word);
+						mIgnoreList.push_back(word);
+					}
+					idxLine++;
+				}
+			}
+		}
+
+		for (dict_list_t::const_iterator it = mDictSecondary.begin(); it != mDictSecondary.end(); ++it)
+		{
+			const LLSD dict_entry = getDictionaryData(*it);
+			if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) )
+			{
+				continue;
+			}
+
+			const std::string filename_dic = dict_entry["name"].asString() + ".dic";
+			if (gDirUtilp->fileExists(user_path + filename_dic))
+			{
+				mHunspell->add_dic((user_path + filename_dic).c_str());
+			}
+			else if (gDirUtilp->fileExists(app_path + filename_dic))
+			{
+				mHunspell->add_dic((app_path + filename_dic).c_str());
+			}
+		}
+	}
+
+	sSettingsChangeSignal();
+}
+
+// static
+const std::string LLSpellChecker::getDictionaryAppPath()
+{
+	std::string dict_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, DICT_DIR, "");
+	return dict_path;
+}
+
+// static
+const std::string LLSpellChecker::getDictionaryUserPath()
+{
+	std::string dict_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DICT_DIR, "");
+	if (!gDirUtilp->fileExists(dict_path))
+	{
+		LLFile::mkdir(dict_path);
+	}
+	return dict_path;
+}
+
+// static
+bool LLSpellChecker::getUseSpellCheck()
+{
+	return (LLSpellChecker::instanceExists()) && (LLSpellChecker::instance().mHunspell);
+}
+
+// static
+bool LLSpellChecker::canRemoveDictionary(const std::string& dict_language)
+{
+	// Only user-installed inactive dictionaries can be removed
+	const LLSD dict_info = getDictionaryData(dict_language);
+	return 
+		(dict_info["user_installed"].asBoolean()) && 
+		( (!getUseSpellCheck()) || (!LLSpellChecker::instance().isActiveDictionary(dict_language)) );
+}
+
+// static
+void LLSpellChecker::removeDictionary(const std::string& dict_language)
+{
+	if (!canRemoveDictionary(dict_language))
+	{
+		return;
+	}
+
+	LLSD dict_map = loadUserDictionaryMap();
+	for (LLSD::array_const_iterator it = dict_map.beginArray(); it != dict_map.endArray(); ++it)
+	{
+		const LLSD& dict_info = *it;
+		if (dict_info["language"].asString() == dict_language)
+		{
+			const std::string dict_dic = getDictionaryUserPath() + dict_info["name"].asString() + ".dic";
+			if (gDirUtilp->fileExists(dict_dic))
+			{
+				LLFile::remove(dict_dic);
+			}
+			const std::string dict_aff = getDictionaryUserPath() + dict_info["name"].asString() + ".aff";
+			if (gDirUtilp->fileExists(dict_aff))
+			{
+				LLFile::remove(dict_aff);
+			}
+			dict_map.erase(it - dict_map.beginArray());
+			break;
+		}
+	}
+	saveUserDictionaryMap(dict_map);
+
+	refreshDictionaryMap();
+}
+
+// static
+LLSD LLSpellChecker::loadUserDictionaryMap()
+{
+	LLSD dict_map;
+	llifstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::binary);
+	if (dict_file.is_open())
+	{
+		LLSDSerialize::fromXMLDocument(dict_map, dict_file);
+		dict_file.close();
+	}
+	return dict_map;
+}
+
+// static
+void LLSpellChecker::saveUserDictionaryMap(const LLSD& dict_map)
+{
+	llofstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::trunc);
+	if (dict_file.is_open())
+	{
+		LLSDSerialize::toPrettyXML(dict_map, dict_file);
+		dict_file.close();
+	}
+}
+
+// static
+boost::signals2::connection LLSpellChecker::setSettingsChangeCallback(const settings_change_signal_t::slot_type& cb)
+{
+	return sSettingsChangeSignal.connect(cb);
+}
+
+// static
+void LLSpellChecker::setUseSpellCheck(const std::string& dict_language)
+{
+	if ( (((dict_language.empty()) && (getUseSpellCheck())) || (!dict_language.empty())) && 
+		 (LLSpellChecker::instance().mDictLanguage != dict_language) )
+	{
+		LLSpellChecker::instance().initHunspell(dict_language);
+	}
+}
+
+// static
+void LLSpellChecker::initClass()
+{
+	if (sDictMap.isUndefined())
+	{
+		refreshDictionaryMap();
+	}
+}
diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ab80195ead318f7f586563474d0f9fb5706d10d
--- /dev/null
+++ b/indra/llui/llspellcheck.h
@@ -0,0 +1,93 @@
+/** 
+ * @file llspellcheck.h
+ * @brief Spell checking functionality
+ *
+ * $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 LLSPELLCHECK_H
+#define LLSPELLCHECK_H
+
+#include "llsingleton.h"
+#include "llui.h"
+#include <boost/signals2.hpp>
+
+class Hunspell;
+
+class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker>
+{
+	friend class LLSingleton<LLSpellChecker>;
+	friend class LLInitClass<LLSpellChecker>;
+protected:
+	LLSpellChecker();
+	~LLSpellChecker();
+
+public:
+	void addToCustomDictionary(const std::string& word);
+	void addToIgnoreList(const std::string& word);
+	bool checkSpelling(const std::string& word) const;
+	S32  getSuggestions(const std::string& word, std::vector<std::string>& suggestions) const;
+protected:
+	void addToDictFile(const std::string& dict_path, const std::string& word);
+	void initHunspell(const std::string& dict_language);
+
+public:
+	typedef std::list<std::string> dict_list_t;
+
+	const std::string&	getPrimaryDictionary() const { return mDictLanguage; }
+	const dict_list_t&	getSecondaryDictionaries() const { return mDictSecondary; }
+	bool				isActiveDictionary(const std::string& dict_language) const;
+	void				setSecondaryDictionaries(dict_list_t dict_list);
+
+	static bool				 canRemoveDictionary(const std::string& dict_language);
+	static const std::string getDictionaryAppPath();
+	static const std::string getDictionaryUserPath();
+	static const LLSD		 getDictionaryData(const std::string& dict_language);
+	static const LLSD&		 getDictionaryMap() { return sDictMap; }
+	static bool				 getUseSpellCheck();
+	static bool				 hasDictionary(const std::string& dict_language, bool check_installed = false);
+	static void				 refreshDictionaryMap();
+	static void				 removeDictionary(const std::string& dict_language);
+	static void				 setUseSpellCheck(const std::string& dict_language);
+protected:
+	static LLSD				 loadUserDictionaryMap();
+	static void				 setDictionaryData(const LLSD& dict_info);
+	static void				 saveUserDictionaryMap(const LLSD& dict_map);
+
+public:
+	typedef boost::signals2::signal<void()> settings_change_signal_t;
+	static boost::signals2::connection setSettingsChangeCallback(const settings_change_signal_t::slot_type& cb);
+protected:
+	static void initClass();
+
+protected:
+	Hunspell*	mHunspell;
+	std::string	mDictLanguage;
+	std::string	mDictFile;
+	dict_list_t	mDictSecondary;
+	std::vector<std::string> mIgnoreList;
+
+	static LLSD						sDictMap;
+	static settings_change_signal_t	sSettingsChangeSignal;
+};
+
+#endif // LLSPELLCHECK_H
diff --git a/indra/llui/llspellcheckmenuhandler.h b/indra/llui/llspellcheckmenuhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..d5c95bad39a7586dddd1e81155ba223b7bac78c3
--- /dev/null
+++ b/indra/llui/llspellcheckmenuhandler.h
@@ -0,0 +1,46 @@
+/** 
+ * @file llspellcheckmenuhandler.h
+ * @brief Interface used by spell check menu handling
+ *
+ * $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 LLSPELLCHECKMENUHANDLER_H
+#define LLSPELLCHECKMENUHANDLER_H
+
+class LLSpellCheckMenuHandler
+{
+public:
+	virtual bool	getSpellCheck() const			{ return false; }
+
+	virtual const std::string& getSuggestion(U32 index) const	{ return LLStringUtil::null; }
+	virtual U32		getSuggestionCount() const		{ return 0; }
+	virtual void	replaceWithSuggestion(U32 index){}
+
+	virtual void	addToDictionary()				{}
+	virtual bool	canAddToDictionary() const		{ return false; }
+
+	virtual void	addToIgnore()					{}
+	virtual bool	canAddToIgnore() const			{ return false; }
+};
+
+#endif // LLSPELLCHECKMENUHANDLER_H
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7aeeae298f754407abcf026372b21c6d6935ba8b..3815eec447e73908208ff8680bd03bc9aa983466 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -32,6 +32,7 @@
 #include "lllocalcliprect.h"
 #include "llmenugl.h"
 #include "llscrollcontainer.h"
+#include "llspellcheck.h"
 #include "llstl.h"
 #include "lltextparser.h"
 #include "lltextutil.h"
@@ -155,6 +156,7 @@ LLTextBase::Params::Params()
 	plain_text("plain_text",false),
 	track_end("track_end", false),
 	read_only("read_only", false),
+	spellcheck("spellcheck", false),
 	v_pad("v_pad", 0),
 	h_pad("h_pad", 0),
 	clip("clip", true),
@@ -181,6 +183,9 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mFontShadow(p.font_shadow),
 	mPopupMenu(NULL),
 	mReadOnly(p.read_only),
+	mSpellCheck(p.spellcheck),
+	mSpellCheckStart(-1),
+	mSpellCheckEnd(-1),
 	mCursorColor(p.cursor_color),
 	mFgColor(p.text_color),
 	mBorderVisible( p.border_visible ),
@@ -246,6 +251,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 		addChild(mDocumentView);
 	}
 
+	if (mSpellCheck)
+	{
+		LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLTextBase::onSpellCheckSettingsChange, this));
+	}
+	mSpellCheckTimer.reset();
+
 	createDefaultSegment();
 
 	updateRects();
@@ -280,12 +291,23 @@ bool LLTextBase::truncate()
 	if (getLength() >= S32(mMaxTextByteLength / 4))
 	{	
 		// Have to check actual byte size
-		LLWString text(getWText());
-		S32 utf8_byte_size = wstring_utf8_length(text);
+		S32 utf8_byte_size = 0;
+		LLSD value = getViewModel()->getValue();
+		if (value.type() == LLSD::TypeString)
+		{
+			// save a copy for strings.
+			utf8_byte_size = value.size();
+		}
+		else
+		{
+			// non string LLSDs need explicit conversion to string
+			utf8_byte_size = value.asString().size();
+		}
+
 		if ( utf8_byte_size > mMaxTextByteLength )
 		{
 			// Truncate safely in UTF-8
-			std::string temp_utf8_text = wstring_to_utf8str(text);
+			std::string temp_utf8_text = value.asString();
 			temp_utf8_text = utf8str_truncate( temp_utf8_text, mMaxTextByteLength );
 			LLWString text = utf8str_to_wstring( temp_utf8_text );
 			// remove extra bit of current string, to preserve formatting, etc.
@@ -530,8 +552,92 @@ void LLTextBase::drawText()
 		return;
 	}
 
+	// Perform spell check if needed
+	if ( (getSpellCheck()) && (getWText().length() > 2) )
+	{
+		// Calculate start and end indices for the spell checking range
+		S32 start = line_start, end = getLineEnd(last_line);
+
+		if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
+		{
+			const LLWString& wstrText = getWText(); 
+			mMisspellRanges.clear();
+
+			segment_set_t::const_iterator seg_it = getSegIterContaining(start);
+			while (mSegments.end() != seg_it)
+			{
+				LLTextSegmentPtr text_segment = *seg_it;
+				if ( (text_segment.isNull()) || (text_segment->getStart() >= end) )
+				{
+					break;
+				}
+
+				if (!text_segment->canEdit())
+				{
+					++seg_it;
+					continue;
+				}
+
+				// Combine adjoining text segments into one
+				U32 seg_start = text_segment->getStart(), seg_end = llmin(text_segment->getEnd(), end);
+				while (mSegments.end() != ++seg_it)
+				{
+					text_segment = *seg_it;
+					if ( (text_segment.isNull()) || (!text_segment->canEdit()) || (text_segment->getStart() >= end) )
+					{
+						break;
+					}
+					seg_end = llmin(text_segment->getEnd(), end);
+				}
+
+				// Find the start of the first word
+				U32 word_start = seg_start, word_end = -1;
+				while ( (word_start < wstrText.length()) && (!LLStringOps::isAlpha(wstrText[word_start])) )
+				{
+					word_start++;
+				}
+
+				// Iterate over all words in the text block and check them one by one
+				while (word_start < seg_end)
+				{
+					// Find the end of the current word (special case handling for "'" when it's used as a contraction)
+					word_end = word_start + 1;
+					while ( (word_end < seg_end) && 
+							((LLWStringUtil::isPartOfWord(wstrText[word_end])) ||
+								((L'\'' == wstrText[word_end]) && 
+								(LLStringOps::isAlnum(wstrText[word_end - 1])) && (LLStringOps::isAlnum(wstrText[word_end + 1])))) )
+					{
+						word_end++;
+					}
+					if (word_end > seg_end)
+					{
+						break;
+					}
+
+					// Don't process words shorter than 3 characters
+					std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
+					if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+					{
+						mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
+					}
+
+					// Find the start of the next word
+					word_start = word_end + 1;
+					while ( (word_start < seg_end) && (!LLWStringUtil::isPartOfWord(wstrText[word_start])) )
+					{
+						word_start++;
+					}
+				}
+			}
+
+			mSpellCheckStart = start;
+			mSpellCheckEnd = end;
+		}
+	}
+
 	LLTextSegmentPtr cur_segment = *seg_iter;
 
+	std::list<std::pair<U32, U32> >::const_iterator misspell_it = std::lower_bound(mMisspellRanges.begin(), mMisspellRanges.end(), std::pair<U32, U32>(line_start, 0));
 	for (S32 cur_line = first_line; cur_line < last_line; cur_line++)
 	{
 		S32 next_line = cur_line + 1;
@@ -566,7 +672,8 @@ void LLTextBase::drawText()
 				cur_segment = *seg_iter;
 			}
 			
-			S32 clipped_end	=	llmin( line_end, cur_segment->getEnd() )  - cur_segment->getStart();
+			S32 seg_end = llmin(line_end, cur_segment->getEnd());
+			S32 clipped_end	= seg_end - cur_segment->getStart();
 
 			if (mUseEllipses								// using ellipses
 				&& clipped_end == line_end					// last segment on line
@@ -578,6 +685,46 @@ void LLTextBase::drawText()
 				text_rect.mRight -= 2;
 			}
 
+			// Draw squiggly lines under any visible misspelled words
+			while ( (mMisspellRanges.end() != misspell_it) && (misspell_it->first < seg_end) && (misspell_it->second > seg_start) )
+			{
+				// Skip the current word if the user is still busy editing it
+				if ( (!mSpellCheckTimer.hasExpired()) && (misspell_it->first <= (U32)mCursorPos) && (misspell_it->second >= (U32)mCursorPos) )
+				{
+					++misspell_it;
+ 					continue;
+				}
+
+				U32 misspell_start = llmax<U32>(misspell_it->first, seg_start), misspell_end = llmin<U32>(misspell_it->second, seg_end);
+				S32 squiggle_start = 0, squiggle_end = 0, pony = 0;
+				cur_segment->getDimensions(seg_start - cur_segment->getStart(), misspell_start - seg_start, squiggle_start, pony);
+				cur_segment->getDimensions(misspell_start - cur_segment->getStart(), misspell_end - misspell_start, squiggle_end, pony);
+				squiggle_start += text_rect.mLeft;
+
+				pony = (squiggle_end + 3) / 6;
+				squiggle_start += squiggle_end / 2 - pony * 3;
+				squiggle_end = squiggle_start + pony * 6;
+
+				S32 squiggle_bottom = text_rect.mBottom + (S32)cur_segment->getStyle()->getFont()->getDescenderHeight();
+
+				gGL.color4ub(255, 0, 0, 200);
+				while (squiggle_start + 1 < squiggle_end)
+				{
+					gl_line_2d(squiggle_start, squiggle_bottom, squiggle_start + 2, squiggle_bottom - 2);
+					if (squiggle_start + 3 < squiggle_end)
+					{
+						gl_line_2d(squiggle_start + 2, squiggle_bottom - 3, squiggle_start + 4, squiggle_bottom - 1);
+					}
+					squiggle_start += 4;
+				}
+
+				if (misspell_it->second > seg_end)
+				{
+					break;
+				}
+				++misspell_it;
+			}
+
 			text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect));
 
 			seg_start = clipped_end + cur_segment->getStart();
@@ -592,8 +739,7 @@ void LLTextBase::drawText()
 
 S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::segment_vec_t* segments )
 {
-	LLWString text(getWText());
-	S32 old_len = text.length();		// length() returns character length
+	S32 old_len = getLength();		// length() returns character length
 	S32 insert_len = wstr.length();
 
 	pos = getEditableIndex(pos, true);
@@ -653,8 +799,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 		}
 	}
 
-	text.insert(pos, wstr);
-	getViewModel()->setDisplay(text);
+	getViewModel()->getEditableDisplay().insert(pos, wstr);
 
 	if ( truncate() )
 	{
@@ -669,7 +814,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 
 S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 {
-	LLWString text(getWText());
 	segment_set_t::iterator seg_iter = getSegIterContaining(pos);
 	while(seg_iter != mSegments.end())
 	{
@@ -715,8 +859,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 		++seg_iter;
 	}
 
-	text.erase(pos, length);
-	getViewModel()->setDisplay(text);
+	getViewModel()->getEditableDisplay().erase(pos, length);
 
 	// recreate default segment in case we erased everything
 	createDefaultSegment();
@@ -733,9 +876,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
 	{
 		return 0;
 	}
-	LLWString text(getWText());
-	text[pos] = wc;
-	getViewModel()->setDisplay(text);
+	getViewModel()->getEditableDisplay()[pos] = wc;
 
 	onValueChange(pos, pos + 1);
 	needsReflow(pos);
@@ -1103,6 +1244,99 @@ void LLTextBase::deselect()
 	mIsSelecting = FALSE;
 }
 
+bool LLTextBase::getSpellCheck() const
+{
+	return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck);
+}
+
+const std::string& LLTextBase::getSuggestion(U32 index) const
+{
+	return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null;
+}
+
+U32 LLTextBase::getSuggestionCount() const
+{
+	return mSuggestionList.size();
+}
+
+void LLTextBase::replaceWithSuggestion(U32 index)
+{
+	for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+	{
+		if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
+		{
+			deselect();
+
+			// Delete the misspelled word
+			removeStringNoUndo(it->first, it->second - it->first);
+
+			// Insert the suggestion in its place
+			LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
+			insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
+			setCursorPos(it->first + (S32)suggestion.length());
+
+			break;
+		}
+	}
+	mSpellCheckStart = mSpellCheckEnd = -1;
+}
+
+void LLTextBase::addToDictionary()
+{
+	if (canAddToDictionary())
+	{
+		LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos));
+	}
+}
+
+bool LLTextBase::canAddToDictionary() const
+{
+	return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+void LLTextBase::addToIgnore()
+{
+	if (canAddToIgnore())
+	{
+		LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos));
+	}
+}
+
+bool LLTextBase::canAddToIgnore() const
+{
+	return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+std::string LLTextBase::getMisspelledWord(U32 pos) const
+{
+	for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+	{
+		if ( (it->first <= pos) && (it->second >= pos) )
+		{
+			return wstring_to_utf8str(getWText().substr(it->first, it->second - it->first));
+		}
+	}
+	return LLStringUtil::null;
+}
+
+bool LLTextBase::isMisspelledWord(U32 pos) const
+{
+	for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+	{
+		if ( (it->first <= pos) && (it->second >= pos) )
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+void LLTextBase::onSpellCheckSettingsChange()
+{
+	// Recheck the spelling on every change
+	mMisspellRanges.clear();
+	mSpellCheckStart = mSpellCheckEnd = -1;
+}
 
 // Sets the scrollbar from the cursor position
 void LLTextBase::updateScrollFromCursor()
@@ -1685,6 +1919,8 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_PARSE_HTML("Parse HTML");
+
 void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
 {
 	LLStyle::Params style_params(input_params);
@@ -1693,15 +1929,13 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
 	S32 part = (S32)LLTextParser::WHOLE;
 	if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
 	{
+		LLFastTimer _(FTM_PARSE_HTML);
 		S32 start=0,end=0;
 		LLUrlMatch match;
 		std::string text = new_text;
 		while ( LLUrlRegistry::instance().findUrl(text, match,
 				boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )
 		{
-			
-			LLTextUtil::processUrlMatch(&match,this);
-
 			start = match.getStart();
 			end = match.getEnd()+1;
 
@@ -1737,6 +1971,8 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
 					}
 			}
 
+			LLTextUtil::processUrlMatch(&match,this);
+
 			// move on to the rest of the text after the Url
 			if (end < (S32)text.length()) 
 			{
@@ -1760,8 +1996,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_APPEND_TEXT("Append Text");
+
 void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
 {
+	LLFastTimer _(FTM_APPEND_TEXT);
 	if (new_text.empty()) 
 		return;
 
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 0549141b72a20531d5b10af3601bbf36eeb52bf9..90b147cee1dfc35d853a3e221dca9a46ea6d22c8 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -30,6 +30,7 @@
 
 #include "v4color.h"
 #include "lleditmenuhandler.h"
+#include "llspellcheckmenuhandler.h"
 #include "llstyle.h"
 #include "llkeywords.h"
 #include "llpanel.h"
@@ -230,7 +231,8 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
 ///
 class LLTextBase 
 :	public LLUICtrl,
-	protected LLEditMenuHandler
+	protected LLEditMenuHandler,
+	public LLSpellCheckMenuHandler
 {
 public:
 	friend class LLTextSegment;
@@ -259,6 +261,7 @@ class LLTextBase
 								border_visible,
 								track_end,
 								read_only,
+								spellcheck,
 								allow_scroll,
 								plain_text,
 								wrap,
@@ -311,6 +314,24 @@ class LLTextBase
 	/*virtual*/ BOOL		canDeselect() const;
 	/*virtual*/ void		deselect();
 
+	// LLSpellCheckMenuHandler overrides
+	/*virtual*/ bool		getSpellCheck() const;
+
+	/*virtual*/ const std::string& getSuggestion(U32 index) const;
+	/*virtual*/ U32			getSuggestionCount() const;
+	/*virtual*/ void		replaceWithSuggestion(U32 index);
+
+	/*virtual*/ void		addToDictionary();
+	/*virtual*/ bool		canAddToDictionary() const;
+
+	/*virtual*/ void		addToIgnore();
+	/*virtual*/ bool		canAddToIgnore() const;
+
+	// Spell checking helper functions
+	std::string				getMisspelledWord(U32 pos) const;
+	bool					isMisspelledWord(U32 pos) const;
+	void					onSpellCheckSettingsChange();
+
 	// used by LLTextSegment layout code
 	bool					getWordWrap() { return mWordWrap; }
 	bool					getUseEllipses() { return mUseEllipses; }
@@ -540,6 +561,14 @@ class LLTextBase
 	
 	BOOL						mIsSelecting;		// Are we in the middle of a drag-select? 
 
+	// spell checking
+	bool						mSpellCheck;
+	S32							mSpellCheckStart;
+	S32							mSpellCheckEnd;
+	LLTimer						mSpellCheckTimer;
+	std::list<std::pair<U32, U32> > mMisspellRanges;
+	std::vector<std::string>		mSuggestionList;
+
 	// configuration
 	S32							mHPad;				// padding on left of text
 	S32							mVPad;				// padding above text
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 6a905b7ec0e952f5775a863c0aaad73472b9ab12..11cfa1d2632cf5223f2308d02050b3211b62a16f 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -150,7 +150,7 @@ S32 LLTextBox::getTextPixelHeight()
 
 LLSD LLTextBox::getValue() const
 {
-	return LLSD(getText());
+	return getViewModel()->getValue();
 }
 
 BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 9720dded6c658e5844fe04a949a5997b4060d742..144b6960a1b03cf090f599207e7c02a5b5410097 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -54,6 +54,7 @@
 #include "llwindow.h"
 #include "lltextparser.h"
 #include "llscrollcontainer.h"
+#include "llspellcheck.h"
 #include "llpanel.h"
 #include "llurlregistry.h"
 #include "lltooltip.h"
@@ -77,6 +78,7 @@ template class LLTextEditor* LLView::getChild<class LLTextEditor>(
 const S32	UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32;
 const S32	UI_TEXTEDITOR_LINE_NUMBER_DIGITS = 4;
 const S32	SPACES_PER_TAB = 4;
+const F32	SPELLCHECK_DELAY = 0.5f;	// delay between the last keypress and spell checking the word the cursor is on
 
 ///////////////////////////////////////////////////////////////////
 
@@ -1953,7 +1955,38 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
 
 	S32 screen_x, screen_y;
 	localPointToScreen(x, y, &screen_x, &screen_y);
-	mContextMenu->show(screen_x, screen_y);
+
+	setCursorAtLocalPos(x, y, false);
+	if (hasSelection())
+	{
+		if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) )
+		{
+			deselect();
+		}
+		else
+		{
+			setCursorPos(llmax(mSelectionStart, mSelectionEnd));
+		}
+	}
+
+	bool use_spellcheck = getSpellCheck(), is_misspelled = false;
+	if (use_spellcheck)
+	{
+		mSuggestionList.clear();
+
+		// If the cursor is on a misspelled word, retrieve suggestions for it
+		std::string misspelled_word = getMisspelledWord(mCursorPos);
+		if ((is_misspelled = !misspelled_word.empty()) == true)
+		{
+			LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList);
+		}
+	}
+
+	mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
+	mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
+	mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
+	mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
+	mContextMenu->show(screen_x, screen_y, this);
 }
 
 
@@ -2838,6 +2871,9 @@ void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& cal
 void LLTextEditor::onKeyStroke()
 {
 	mKeystrokeSignal(this);
+
+	mSpellCheckStart = mSpellCheckEnd = -1;
+	mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
 }
 
 //virtual
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b5e27616b72c74261820f8bae9078e44fe8bd24d..87bf518aa17ca6c46b891627f344bc57eb9b7f7f 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -831,7 +831,11 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
 
 	gGL.flush();
 	glLineWidth(2.5f);
-	glLineStipple(2, 0x3333 << shift);
+
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glLineStipple(2, 0x3333 << shift);
+	}
 
 	gGL.begin(LLRender::LINES);
 	{
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 763af5d8a2caacf26ec3cafc650d255885510b22..ef2e3147992801c9d60fc2bf301983df28797201 100644
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -102,6 +102,7 @@ class LLTextViewModel: public LLViewModel
 	// New functions
     /// Get the stored value in string form
     const LLWString& getDisplay() const { return mDisplay; }
+	LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; }
 
     /**
      * Set the display string directly (see LLTextEditor). What the user is
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 53cecf9d4a70291fec32c2e5dddcdfacb4cca287..8b356ba1387099345db95809228b1e8f49e9e235 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -46,7 +46,7 @@ LLKeyStringTranslatorFunc*	LLKeyboard::mStringTranslator = NULL;	// Used for l10
 // Class Implementation
 //
 
-LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF)
+LLKeyboard::LLKeyboard() : mCallbacks(NULL)
 {
 	S32 i;
 
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index ba472cfde5633c1ad80fc95273acc761c91981f2..c155c1b3626092c2b3a738ab08dd4a6afa9dea2c 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -62,14 +62,6 @@ class LLWindowCallbacks;
 
 class LLKeyboard
 {
-public:
-	typedef enum e_numpad_distinct
-	{
-		ND_NEVER,
-		ND_NUMLOCK_OFF,
-		ND_NUMLOCK_ON
-	} ENumpadDistinct;
-
 public:
 	LLKeyboard();
 	virtual ~LLKeyboard();
@@ -107,8 +99,6 @@ class LLKeyboard
 	static BOOL		keyFromString(const std::string& str, KEY *key);			// False on failure
 	static std::string stringFromKey(KEY key);
 	static std::string stringFromAccelerator( MASK accel_mask, KEY key );
-	e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; }
-	void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; }
 
 	void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
 	F32				getKeyElapsedTime( KEY key );  // Returns time in seconds since key was pressed.
@@ -135,8 +125,6 @@ class LLKeyboard
 
 	static LLKeyStringTranslatorFunc*	mStringTranslator;	// Used for l10n + PC/Mac/Linux accelerator labeling
 	
-	e_numpad_distinct mNumpadDistinct;
-
 	EKeyboardInsertMode mInsertMode;
 
 	static std::map<KEY,std::string> sKeysToNames;
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index ecc2631669557eb2ce85f632727281c21d75ad4e..7f8f303517052671ac394681d0f5d1b0d78fc2f2 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -299,28 +299,11 @@ void LLKeyboardMacOSX::scanKeyboard()
 
 BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key )
 {
-	if(mNumpadDistinct == ND_NUMLOCK_ON)
-	{
-		std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
-		if(iter != mTranslateNumpadMap.end())
-		{
-			*translated_key = iter->second;
-			return TRUE;
-		}
-	}
 	return translateKey(os_key, translated_key);
 }
 
 U16	LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key)
 {
-	if(mNumpadDistinct == ND_NUMLOCK_ON)
-	{
-		std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
-		if(iter != mInvTranslateNumpadMap.end())
-		{
-			return iter->second;
-		}
-	}
 	return inverseTranslateKey(translated_key);
 }
 
diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp
index 4bb9603368cdc3d5d787ecaad31cc30c40e19b4d..7c9aa1d340d41dfb1b7bb90b6d4ac636727c783a 100644
--- a/indra/llwindow/llkeyboardsdl.cpp
+++ b/indra/llwindow/llkeyboardsdl.cpp
@@ -312,29 +312,11 @@ void LLKeyboardSDL::scanKeyboard()
  
 BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
 {
-	if(mNumpadDistinct == ND_NUMLOCK_ON)
-	{
-		std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
-		if(iter != mTranslateNumpadMap.end())
-		{
-			*translated_key = iter->second;
-			return TRUE;
-		}
-	}
-	BOOL success = translateKey(os_key, translated_key);
-	return success;	
+	return translateKey(os_key, translated_key);	
 }
 
 U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
 {
-	if(mNumpadDistinct == ND_NUMLOCK_ON)
-	{
-		std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
-		if(iter != mInvTranslateNumpadMap.end())
-		{
-			return iter->second;
-		}
-	}
 	return inverseTranslateKey(translated_key);
 }
 
diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index df78816bd67e21c2ea33bb2afc32593267d1aac2..be3fe5deb056426b8ce852cba1443cf9c77e42bd 100644
--- a/indra/llwindow/llkeyboardwin32.cpp
+++ b/indra/llwindow/llkeyboardwin32.cpp
@@ -299,69 +299,13 @@ void LLKeyboardWin32::scanKeyboard()
 
 BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key)
 {
-	if(mNumpadDistinct == ND_NUMLOCK_ON)
-	{
-		std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key);
-		if (iter != mTranslateNumpadMap.end())
-		{
-			*translated_key = iter->second;
-			return TRUE;
-		}
-	}
-
-	BOOL success = translateKey(os_key, translated_key);
-	if(mNumpadDistinct != ND_NEVER) {
-		if(!success) return success;
-		if(mask & MASK_EXTENDED) 
-		{
-			// this is where we'd create new keycodes for extended keys
-			// the set of extended keys includes the 'normal' arrow keys and 
-			// the pgup/dn/insert/home/end/delete cluster above the arrow keys
-			// see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx
-
-			// only process the return key if numlock is off
-			if(((mNumpadDistinct == ND_NUMLOCK_OFF && 
-				 !(GetKeyState(VK_NUMLOCK) & 1)) 
-				 || mNumpadDistinct == ND_NUMLOCK_ON) &&
-					*translated_key == KEY_RETURN) {
-					*translated_key = KEY_PAD_RETURN;
-			}
-		}
-		else 
-		{
-			// the non-extended keys, those are in the numpad
-			switch (*translated_key) 
-			{
-				case KEY_LEFT:
-					*translated_key = KEY_PAD_LEFT; break;
-				case KEY_RIGHT: 
-					*translated_key = KEY_PAD_RIGHT; break;
-				case KEY_UP: 
-					*translated_key = KEY_PAD_UP; break;
-				case KEY_DOWN:
-					*translated_key = KEY_PAD_DOWN; break;
-				case KEY_HOME:
-					*translated_key = KEY_PAD_HOME; break;
-				case KEY_END:
-					*translated_key = KEY_PAD_END; break;
-				case KEY_PAGE_UP:
-					*translated_key = KEY_PAD_PGUP; break;
-				case KEY_PAGE_DOWN:
-					*translated_key = KEY_PAD_PGDN; break;
-				case KEY_INSERT:
-					*translated_key = KEY_PAD_INS; break;
-				case KEY_DELETE:
-					*translated_key = KEY_PAD_DEL; break;
-			}
-		}
-	}
-	return success;
+	return translateKey(os_key, translated_key);
 }
 
 U16  LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key)
 {
 	// if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number
-	if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1))
+	if(GetKeyState(VK_NUMLOCK) & 1)
 	{
 		std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key);
 		if (iter != mInvTranslateNumpadMap.end())
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index e07fbddb944536c073a4848e6f4e294070992f3e..6f0d90be06765fa03801977592efdbddc86a8793 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -367,6 +367,10 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 							 U32 fsaa_samples)
 	: LLWindow(callbacks, fullscreen, flags)
 {
+	
+	//MAINT-516 -- force a load of opengl32.dll just in case windows went sideways 
+	LoadLibrary(L"opengl32.dll");
+
 	mFSAASamples = fsaa_samples;
 	mIconResource = gIconResource;
 	mOverrideAspectRatio = 0.f;
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 0809d956281c0fca42d8013aea2388a75094a010..53d9380f4f85a6ee251e8e97b91b2adf561dc054 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -201,7 +201,8 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
 	}
 	
 	LLSD storable_value = getComparableValue(new_value);
-	bool value_changed = llsd_compare(getValue(), storable_value) == FALSE;
+	LLSD original_value = getValue();
+	bool value_changed = llsd_compare(original_value, storable_value) == FALSE;
 	if(saved_value)
 	{
     	// If we're going to save this value, return to default but don't fire
@@ -237,7 +238,7 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
 
     if(value_changed)
     {
-        mCommitSignal(this, storable_value); 
+		firePropertyChanged(original_value);
     }
 }
 
@@ -249,12 +250,13 @@ void LLControlVariable::setDefaultValue(const LLSD& value)
 	// *NOTE: Default values are not saved, only read.
 
 	LLSD comparable_value = getComparableValue(value);
-	bool value_changed = (llsd_compare(getValue(), comparable_value) == FALSE);
+	LLSD original_value = getValue();
+	bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE);
 	resetToDefault(false);
 	mValues[0] = comparable_value;
 	if(value_changed)
 	{
-		firePropertyChanged();
+		firePropertyChanged(original_value);
 	}
 }
 
@@ -277,6 +279,8 @@ void LLControlVariable::resetToDefault(bool fire_signal)
 {
 	//The first setting is always the default
 	//Pop to it and fire off the listener
+	LLSD originalValue = mValues.back();
+
 	while(mValues.size() > 1)
 	{
 		mValues.pop_back();
@@ -284,7 +288,7 @@ void LLControlVariable::resetToDefault(bool fire_signal)
 	
 	if(fire_signal) 
 	{
-		firePropertyChanged();
+		firePropertyChanged(originalValue);
 	}
 }
 
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 597031ec707a6dd09b8db07be710685f16d8a330..9a3a40e476f0395e481e5d5b295c18183c167823 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -98,7 +98,7 @@ class LLControlVariable : public LLRefCount
 	
 public:
 	typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
-	typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
+	typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t;
 
 private:
 	std::string		mName;
@@ -146,11 +146,11 @@ class LLControlVariable : public LLRefCount
 	void setHiddenFromSettingsEditor(bool hide);
 	void setComment(const std::string& comment);
 
-	void firePropertyChanged()
+private:
+	void firePropertyChanged(const LLSD &pPreviousValue)
 	{
-		mCommitSignal(this, mValues.back());
+		mCommitSignal(this, mValues.back(), pPreviousValue);
 	}
-private:
 	LLSD getComparableValue(const LLSD& value);
 	bool llsd_compare(const LLSD& a, const LLSD & b);
 };
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0a267cbad010390fd0d8bc1f32980acbabeda914..65170a214099dc8511d1b4e2900649a463e533a0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -13,6 +13,7 @@ include(EXPAT)
 include(FMOD)
 include(OPENAL)
 include(FindOpenGL)
+include(Hunspell)
 include(JsonCpp)
 include(LLAudio)
 include(LLCharacter)
@@ -70,6 +71,7 @@ include_directories(
     ${LLLOGIN_INCLUDE_DIRS}
     ${UPDATER_INCLUDE_DIRS}
     ${LIBS_PREBUILT_DIR}/include/collada
+    ${LIBS_PREBUILD_DIR}/include/hunspell
     ${OPENAL_LIB_INCLUDE_DIRS}
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     )
@@ -96,6 +98,7 @@ set(viewer_SOURCE_FILES
     llassetuploadresponders.cpp
     llattachmentsmgr.cpp
     llaudiosourcevo.cpp
+    llautoreplace.cpp
     llavataractions.cpp
     llavatariconctrl.cpp
     llavatarlist.cpp
@@ -167,6 +170,7 @@ set(viewer_SOURCE_FILES
     llfloaterabout.cpp
     llfloaterbvhpreview.cpp
     llfloaterauction.cpp
+    llfloaterautoreplacesettings.cpp
     llfloateravatar.cpp
     llfloateravatarpicker.cpp
     llfloateravatartextures.cpp
@@ -210,7 +214,6 @@ set(viewer_SOURCE_FILES
     llfloatermemleak.cpp
     llfloatermodelpreview.cpp
     llfloatermodeluploadbase.cpp
-    llfloatermodelwizard.cpp
     llfloaternamedesc.cpp
     llfloaternotificationsconsole.cpp
     llfloaterobjectweights.cpp
@@ -232,6 +235,7 @@ set(viewer_SOURCE_FILES
     llfloatersidepanelcontainer.cpp
     llfloatersnapshot.cpp
     llfloatersounddevices.cpp
+    llfloaterspellchecksettings.cpp
     llfloatertelehub.cpp
     llfloatertestinspectors.cpp
     llfloatertestlistview.cpp
@@ -654,6 +658,7 @@ set(viewer_HEADER_FILES
     llassetuploadresponders.h
     llattachmentsmgr.h
     llaudiosourcevo.h
+    llautoreplace.h
     llavataractions.h
     llavatariconctrl.h
     llavatarlist.h
@@ -725,6 +730,7 @@ set(viewer_HEADER_FILES
     llfloaterabout.h
     llfloaterbvhpreview.h
     llfloaterauction.h
+    llfloaterautoreplacesettings.h
     llfloateravatar.h
     llfloateravatarpicker.h
     llfloateravatartextures.h
@@ -768,7 +774,6 @@ set(viewer_HEADER_FILES
     llfloatermemleak.h
     llfloatermodelpreview.h
     llfloatermodeluploadbase.h
-    llfloatermodelwizard.h
     llfloaternamedesc.h
     llfloaternotificationsconsole.h
     llfloaterobjectweights.h
@@ -790,6 +795,7 @@ set(viewer_HEADER_FILES
     llfloatersidepanelcontainer.h
     llfloatersnapshot.h
     llfloatersounddevices.h
+    llfloaterspellchecksettings.h
     llfloatertelehub.h
     llfloatertestinspectors.h
     llfloatertestlistview.h
@@ -1574,6 +1580,9 @@ if (WINDOWS)
       ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll
       ${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll
       ${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll
+      ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
+      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
+      ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
       ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
       ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll
       ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll
@@ -1752,6 +1761,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLMATH_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
     ${NDOF_LIBRARY}
+    ${HUNSPELL_LIBRARY}
     ${viewer_LIBRARIES}
     ${BOOST_PROGRAM_OPTIONS_LIBRARY}
     ${BOOST_REGEX_LIBRARY}
diff --git a/indra/newview/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..09d19f7b04154b72167444d25e8d3207abbf217f
--- /dev/null
+++ b/indra/newview/app_settings/autoreplace.xml
@@ -0,0 +1,8330 @@
+<llsd>
+  <array>
+    <map>
+      <key>name</key>
+      <string>Abbreviations</string>
+      <key>replacements</key>
+      <map>
+        <key>afaic</key>
+        <string>As far as I am concerned</string>
+        <key>afaik</key>
+        <string>As far as I know</string>
+        <key>afk</key>
+        <string>away from keyboard</string>
+        <key>atm</key>
+        <string>at the moment</string>
+        <key>bbiab</key>
+        <string>be back in a bit</string>
+        <key>bbl</key>
+        <string>be back later</string>
+        <key>brb</key>
+        <string>be right back</string>
+        <key>btw</key>
+        <string>by the way</string>
+        <key>fyi</key>
+        <string>For your information</string>
+        <key>fwiw</key>
+        <string>For what its worth</string>
+        <key>gtg</key>
+        <string>got to go</string>
+        <key>idk</key>
+        <string>I don't know</string>
+        <key>iirc</key>
+        <string>if I recall correctly</string>
+        <key>imho</key>
+        <string>in my humble opinion</string>
+        <key>imo</key>
+        <string>in my opinion</string>
+        <key>irl</key>
+        <string>in real life</string>
+        <key>np</key>
+        <string>no problem</string>
+        <key>nsfw</key>
+        <string>not safe for work</string>
+        <key>nvm</key>
+        <string>nevermind</string>
+        <key>tc</key>
+        <string>take care</string>
+        <key>thx</key>
+        <string>thanks</string>
+        <key>ttfn</key>
+        <string>ta-ta for now</string>
+        <key>ttyl</key>
+        <string>talk to you later</string>
+        <key>ty</key>
+        <string>thank you</string>
+        <key>tyvm</key>
+        <string>thank you very much</string>
+        <key>wb</key>
+        <string>welcome back</string>
+        <key>yw</key>
+        <string>you&apos;re welcome</string>
+        <key>yvw</key>
+        <string>you&apos;re very welcome</string>
+      </map>
+    </map>
+    <map>
+      <key>name</key>
+      <string>Spelling Corrections</string>
+      <key>replacements</key>
+      <map>
+        <key>Amercia</key>
+        <string>America</string>
+        <key>Bernouilli</key>
+        <string>Bernoulli</string>
+        <key>Blitzkreig</key>
+        <string>Blitzkrieg</string>
+        <key>Bonnano</key>
+        <string>Bonanno</string>
+        <key>Brasillian</key>
+        <string>Brazilian</string>
+        <key>Britian</key>
+        <string>Britain</string>
+        <key>Brittish</key>
+        <string>British</string>
+        <key>Buddah</key>
+        <string>Buddha</string>
+        <key>Buddist</key>
+        <string>Buddhist</string>
+        <key>Cambrige</key>
+        <string>Cambridge</string>
+        <key>Capetown</key>
+        <string>Cape Town</string>
+        <key>Carmalite</key>
+        <string>Carmelite</string>
+        <key>Carnagie</key>
+        <string>Carnegie</string>
+        <key>Carnagie-Mellon</key>
+        <string>Carnegie-Mellon</string>
+        <key>Carnigie</key>
+        <string>Carnegie</string>
+        <key>Carnigie-Mellon</key>
+        <string>Carnegie-Mellon</string>
+        <key>Carribbean</key>
+        <string>Caribbean</string>
+        <key>Carribean</key>
+        <string>Caribbean</string>
+        <key>Carthagian</key>
+        <string>Carthaginian</string>
+        <key>Cataline</key>
+        <string>Catiline</string>
+        <key>Ceasar</key>
+        <string>Caesar</string>
+        <key>Celcius</key>
+        <string>Celsius</string>
+        <key>Champange</key>
+        <string>Champagne</string>
+        <key>Cincinatti</key>
+        <string>Cincinnati</string>
+        <key>Cincinnatti</key>
+        <string>Cincinnati</string>
+        <key>Conneticut</key>
+        <string>Connecticut</string>
+        <key>Dardenelles</key>
+        <string>Dardanelles</string>
+        <key>Dravadian</key>
+        <string>Dravidian</string>
+        <key>Enlish</key>
+        <string>English</string>
+        <key>Europian</key>
+        <string>European</string>
+        <key>Europians</key>
+        <string>Europeans</string>
+        <key>Eurpean</key>
+        <string>European</string>
+        <key>Eurpoean</key>
+        <string>European</string>
+        <key>Farenheit</key>
+        <string>Fahrenheit</string>
+        <key>Febuary</key>
+        <string>February</string>
+        <key>Feburary</key>
+        <string>February</string>
+        <key>Flemmish</key>
+        <string>Flemish</string>
+        <key>Formalhaut</key>
+        <string>Fomalhaut</string>
+        <key>Foundland</key>
+        <string>Newfoundland</string>
+        <key>Fransiscan</key>
+        <string>Franciscan</string>
+        <key>Fransiscans</key>
+        <string>Franciscans</string>
+        <key>Galations</key>
+        <string>Galatians</string>
+        <key>Gameboy</key>
+        <string>Game Boy</string>
+        <key>Ghandi</key>
+        <string>Gandhi</string>
+        <key>Godounov</key>
+        <string>Godunov</string>
+        <key>Gothenberg</key>
+        <string>Gothenburg</string>
+        <key>Gottleib</key>
+        <string>Gottlieb</string>
+        <key>Guaduloupe</key>
+        <string>Guadalupe</string>
+        <key>Guadulupe</key>
+        <string>Guadalupe</string>
+        <key>Guatamala</key>
+        <string>Guatemala</string>
+        <key>Guatamalan</key>
+        <string>Guatemalan</string>
+        <key>Guilia</key>
+        <string>Giulia</string>
+        <key>Guilio</key>
+        <string>Giulio</string>
+        <key>Guiness</key>
+        <string>Guinness</string>
+        <key>Guiseppe</key>
+        <string>Giuseppe</string>
+        <key>Habsbourg</key>
+        <string>Habsburg</string>
+        <key>Hallowean</key>
+        <string>Halloween</string>
+        <key>Heidelburg</key>
+        <string>Heidelberg</string>
+        <key>Ihaca</key>
+        <string>Ithaca</string>
+        <key>Israelies</key>
+        <string>Israelis</string>
+        <key>Janurary</key>
+        <string>January</string>
+        <key>Januray</key>
+        <string>January</string>
+        <key>Japanes</key>
+        <string>Japanese</string>
+        <key>Johanine</key>
+        <string>Johannine</string>
+        <key>Jospeh</key>
+        <string>Joseph</string>
+        <key>Juadaism</key>
+        <string>Judaism</string>
+        <key>Juadism</key>
+        <string>Judaism</string>
+        <key>Lybia</key>
+        <string>Libya</string>
+        <key>Malcom</key>
+        <string>Malcolm</string>
+        <key>Massachussets</key>
+        <string>Massachusetts</string>
+        <key>Massachussetts</key>
+        <string>Massachusetts</string>
+        <key>Mediteranean</key>
+        <string>Mediterranean</string>
+        <key>Michagan</key>
+        <string>Michigan</string>
+        <key>Misouri</key>
+        <string>Missouri</string>
+        <key>Missisipi</key>
+        <string>Mississippi</string>
+        <key>Missisippi</key>
+        <string>Mississippi</string>
+        <key>Monserrat</key>
+        <string>Montserrat</string>
+        <key>Montnana</key>
+        <string>Montana</string>
+        <key>Morisette</key>
+        <string>Morissette</string>
+        <key>Morrisette</key>
+        <string>Morissette</string>
+        <key>Mythraic</key>
+        <string>Mithraic</string>
+        <key>Naploeon</key>
+        <string>Napoleon</string>
+        <key>Napolean</key>
+        <string>Napoleon</string>
+        <key>Napoleonian</key>
+        <string>Napoleonic</string>
+        <key>Nazereth</key>
+        <string>Nazareth</string>
+        <key>Newyorker</key>
+        <string>New Yorker</string>
+        <key>Novermber</key>
+        <string>November</string>
+        <key>Nullabour</key>
+        <string>Nullarbor</string>
+        <key>Nuremburg</key>
+        <string>Nuremberg</string>
+        <key>Palistian</key>
+        <string>Palestinian</string>
+        <key>Palistinian</key>
+        <string>Palestinian</string>
+        <key>Palistinians</key>
+        <string>Palestinians</string>
+        <key>Papanicalou</key>
+        <string>Papanicolaou</string>
+        <key>Peloponnes</key>
+        <string>Peloponnesus</string>
+        <key>Pennyslvania</key>
+        <string>Pennsylvania</string>
+        <key>Pharoah</key>
+        <string>Pharaoh</string>
+        <key>Philipines</key>
+        <string>Philippines</string>
+        <key>Phillipine</key>
+        <string>Philippine</string>
+        <key>Phillipines</key>
+        <string>Philippines</string>
+        <key>Phillippines</key>
+        <string>Philippines</string>
+        <key>Phonecian</key>
+        <string>Phoenecian</string>
+        <key>Portugese</key>
+        <string>Portuguese</string>
+        <key>Postdam</key>
+        <string>Potsdam</string>
+        <key>Premonasterians</key>
+        <string>Premonstratensians</string>
+        <key>Pucini</key>
+        <string>Puccini</string>
+        <key>Puertorrican</key>
+        <string>Puerto Rican</string>
+        <key>Puertorricans</key>
+        <string>Puerto Ricans</string>
+        <key>Queenland</key>
+        <string>Queensland</string>
+        <key>Rockerfeller</key>
+        <string>Rockefeller</string>
+        <key>Russion</key>
+        <string>Russian</string>
+        <key>Sanhedrim</key>
+        <string>Sanhedrin</string>
+        <key>Saterday</key>
+        <string>Saturday</string>
+        <key>Saterdays</key>
+        <string>Saturdays</string>
+        <key>Sionist</key>
+        <string>Zionist</string>
+        <key>Sionists</key>
+        <string>Zionists</string>
+        <key>Sixtin</key>
+        <string>Sistine</string>
+        <key>Skagerak</key>
+        <string>Skagerrak</string>
+        <key>Tolkein</key>
+        <string>Tolkien</string>
+        <key>Tuscon</key>
+        <string>Tucson</string>
+        <key>Ukranian</key>
+        <string>Ukrainian</string>
+        <key>UnitesStates</key>
+        <string>UnitedStates</string>
+        <key>Yementite</key>
+        <string>Yemenite</string>
+        <key>abandonned</key>
+        <string>abandoned</string>
+        <key>aberation</key>
+        <string>aberration</string>
+        <key>abilties</key>
+        <string>abilities</string>
+        <key>abilty</key>
+        <string>ability</string>
+        <key>abondon</key>
+        <string>abandon</string>
+        <key>abondoned</key>
+        <string>abandoned</string>
+        <key>abondoning</key>
+        <string>abandoning</string>
+        <key>abondons</key>
+        <string>abandons</string>
+        <key>aborigene</key>
+        <string>aborigine</string>
+        <key>abortificant</key>
+        <string>abortifacient</string>
+        <key>abreviate</key>
+        <string>abbreviate</string>
+        <key>abreviated</key>
+        <string>abbreviated</string>
+        <key>abreviation</key>
+        <string>abbreviation</string>
+        <key>abritrary</key>
+        <string>arbitrary</string>
+        <key>absail</key>
+        <string>abseil</string>
+        <key>absailing</key>
+        <string>abseiling</string>
+        <key>absense</key>
+        <string>absence</string>
+        <key>absolutly</key>
+        <string>absolutely</string>
+        <key>absorbsion</key>
+        <string>absorption</string>
+        <key>absorbtion</key>
+        <string>absorption</string>
+        <key>abundacies</key>
+        <string>abundances</string>
+        <key>abundancies</key>
+        <string>abundances</string>
+        <key>abundunt</key>
+        <string>abundant</string>
+        <key>abutts</key>
+        <string>abuts</string>
+        <key>acadamy</key>
+        <string>academy</string>
+        <key>acadmic</key>
+        <string>academic</string>
+        <key>accademic</key>
+        <string>academic</string>
+        <key>accademy</key>
+        <string>academy</string>
+        <key>acccused</key>
+        <string>accused</string>
+        <key>accelleration</key>
+        <string>acceleration</string>
+        <key>accension</key>
+        <string>ascension</string>
+        <key>acceptence</key>
+        <string>acceptance</string>
+        <key>acceptible</key>
+        <string>acceptable</string>
+        <key>accessable</key>
+        <string>accessible</string>
+        <key>accidentaly</key>
+        <string>accidentally</string>
+        <key>accidently</key>
+        <string>accidentally</string>
+        <key>acclimitization</key>
+        <string>acclimatization</string>
+        <key>accomadate</key>
+        <string>accommodate</string>
+        <key>accomadated</key>
+        <string>accommodated</string>
+        <key>accomadates</key>
+        <string>accommodates</string>
+        <key>accomadating</key>
+        <string>accommodating</string>
+        <key>accomadation</key>
+        <string>accommodation</string>
+        <key>accomadations</key>
+        <string>accommodations</string>
+        <key>accomdate</key>
+        <string>accommodate</string>
+        <key>accomodate</key>
+        <string>accommodate</string>
+        <key>accomodated</key>
+        <string>accommodated</string>
+        <key>accomodates</key>
+        <string>accommodates</string>
+        <key>accomodating</key>
+        <string>accommodating</string>
+        <key>accomodation</key>
+        <string>accommodation</string>
+        <key>accomodations</key>
+        <string>accommodations</string>
+        <key>accompanyed</key>
+        <string>accompanied</string>
+        <key>accordeon</key>
+        <string>accordion</string>
+        <key>accordian</key>
+        <string>accordion</string>
+        <key>accoring</key>
+        <string>according</string>
+        <key>accoustic</key>
+        <string>acoustic</string>
+        <key>accquainted</key>
+        <string>acquainted </string>
+        <key>accrediation</key>
+        <string>accreditation</string>
+        <key>accredidation</key>
+        <string>accreditation</string>
+        <key>accross</key>
+        <string>across</string>
+        <key>accussed</key>
+        <string>accused</string>
+        <key>acedemic</key>
+        <string>academic</string>
+        <key>acheive</key>
+        <string>achieve</string>
+        <key>acheived</key>
+        <string>achieved</string>
+        <key>acheivement</key>
+        <string>achievement</string>
+        <key>acheivements</key>
+        <string>achievements</string>
+        <key>acheives</key>
+        <string>achieves</string>
+        <key>acheiving</key>
+        <string>achieving</string>
+        <key>acheivment</key>
+        <string>achievement</string>
+        <key>acheivments</key>
+        <string>achievements</string>
+        <key>achievment</key>
+        <string>achievement</string>
+        <key>achievments</key>
+        <string>achievements</string>
+        <key>achivement</key>
+        <string>achievement</string>
+        <key>achivements</key>
+        <string>achievements</string>
+        <key>acknowldeged</key>
+        <string>acknowledged</string>
+        <key>acknowledgeing</key>
+        <string>acknowledging</string>
+        <key>ackward</key>
+        <string>awkward</string>
+        <key>acommodate</key>
+        <string>accommodate</string>
+        <key>acomplish</key>
+        <string>accomplish</string>
+        <key>acomplished</key>
+        <string>accomplished</string>
+        <key>acomplishment</key>
+        <string>accomplishment</string>
+        <key>acomplishments</key>
+        <string>accomplishments</string>
+        <key>acording</key>
+        <string>according</string>
+        <key>acordingly</key>
+        <string>accordingly</string>
+        <key>acquaintence</key>
+        <string>acquaintance</string>
+        <key>acquaintences</key>
+        <string>acquaintances</string>
+        <key>acquiantence</key>
+        <string>acquaintance</string>
+        <key>acquiantences</key>
+        <string>acquaintances</string>
+        <key>acquited</key>
+        <string>acquitted</string>
+        <key>activites</key>
+        <string>activities</string>
+        <key>activly</key>
+        <string>actively</string>
+        <key>actualy</key>
+        <string>actually</string>
+        <key>acuracy</key>
+        <string>accuracy</string>
+        <key>acused</key>
+        <string>accused</string>
+        <key>acustom</key>
+        <string>accustom</string>
+        <key>acustommed</key>
+        <string>accustomed</string>
+        <key>adavanced</key>
+        <string>advanced</string>
+        <key>adbandon</key>
+        <string>abandon</string>
+        <key>additinally</key>
+        <string>additionally</string>
+        <key>additionaly</key>
+        <string>additionally</string>
+        <key>additonal</key>
+        <string>additional</string>
+        <key>additonally</key>
+        <string>additionally</string>
+        <key>addmission</key>
+        <string>admission</string>
+        <key>addopt</key>
+        <string>adopt</string>
+        <key>addopted</key>
+        <string>adopted</string>
+        <key>addoptive</key>
+        <string>adoptive</string>
+        <key>addres</key>
+        <string>address</string>
+        <key>addresable</key>
+        <string>addressable</string>
+        <key>addresed</key>
+        <string>addressed</string>
+        <key>addresing</key>
+        <string>addressing</string>
+        <key>addressess</key>
+        <string>addresses</string>
+        <key>addtion</key>
+        <string>addition</string>
+        <key>addtional</key>
+        <string>additional</string>
+        <key>adecuate</key>
+        <string>adequate</string>
+        <key>adequit</key>
+        <string>adequate</string>
+        <key>adhearing</key>
+        <string>adhering</string>
+        <key>adherance</key>
+        <string>adherence</string>
+        <key>admendment</key>
+        <string>amendment</string>
+        <key>admininistrative</key>
+        <string>administrative</string>
+        <key>adminstered</key>
+        <string>administered</string>
+        <key>adminstrate</key>
+        <string>administrate</string>
+        <key>adminstration</key>
+        <string>administration</string>
+        <key>adminstrative</key>
+        <string>administrative</string>
+        <key>adminstrator</key>
+        <string>administrator</string>
+        <key>admissability</key>
+        <string>admissibility</string>
+        <key>admissable</key>
+        <string>admissible</string>
+        <key>admited</key>
+        <string>admitted</string>
+        <key>admitedly</key>
+        <string>admittedly</string>
+        <key>adn</key>
+        <string>and</string>
+        <key>adolecent</key>
+        <string>adolescent</string>
+        <key>adquire</key>
+        <string>acquire</string>
+        <key>adquired</key>
+        <string>acquired</string>
+        <key>adquires</key>
+        <string>acquires</string>
+        <key>adquiring</key>
+        <string>acquiring</string>
+        <key>adres</key>
+        <string>address</string>
+        <key>adresable</key>
+        <string>addressable</string>
+        <key>adresing</key>
+        <string>addressing</string>
+        <key>adress</key>
+        <string>address</string>
+        <key>adressable</key>
+        <string>addressable</string>
+        <key>adressed</key>
+        <string>addressed</string>
+        <key>adressing</key>
+        <string>addressing</string>
+        <key>adventrous</key>
+        <string>adventurous</string>
+        <key>advertisment</key>
+        <string>advertisement</string>
+        <key>advertisments</key>
+        <string>advertisements</string>
+        <key>advesary</key>
+        <string>adversary</string>
+        <key>adviced</key>
+        <string>advised</string>
+        <key>aeriel</key>
+        <string>aerial</string>
+        <key>aeriels</key>
+        <string>aerials</string>
+        <key>afair</key>
+        <string>affair</string>
+        <key>afficianados</key>
+        <string>aficionados</string>
+        <key>afficionado</key>
+        <string>aficionado</string>
+        <key>afficionados</key>
+        <string>aficionados</string>
+        <key>affilate</key>
+        <string>affiliate</string>
+        <key>affilliate</key>
+        <string>affiliate</string>
+        <key>affort</key>
+        <string>afford</string>
+        <key>aforememtioned</key>
+        <string>aforementioned</string>
+        <key>againnst</key>
+        <string>against</string>
+        <key>agains</key>
+        <string>against</string>
+        <key>agaisnt</key>
+        <string>against</string>
+        <key>aganist</key>
+        <string>against</string>
+        <key>aggaravates</key>
+        <string>aggravates</string>
+        <key>aggreed</key>
+        <string>agreed</string>
+        <key>aggreement</key>
+        <string>agreement</string>
+        <key>aggregious</key>
+        <string>egregious</string>
+        <key>aggresive</key>
+        <string>aggressive</string>
+        <key>agian</key>
+        <string>again</string>
+        <key>agianst</key>
+        <string>against</string>
+        <key>agin</key>
+        <string>again</string>
+        <key>agina</key>
+        <string>again</string>
+        <key>aginst</key>
+        <string>against</string>
+        <key>agravate</key>
+        <string>aggravate</string>
+        <key>agre</key>
+        <string>agree</string>
+        <key>agred</key>
+        <string>agreed</string>
+        <key>agreeement</key>
+        <string>agreement</string>
+        <key>agreemnt</key>
+        <string>agreement</string>
+        <key>agregate</key>
+        <string>aggregate</string>
+        <key>agregates</key>
+        <string>aggregates</string>
+        <key>agreing</key>
+        <string>agreeing</string>
+        <key>agression</key>
+        <string>aggression</string>
+        <key>agressive</key>
+        <string>aggressive</string>
+        <key>agressively</key>
+        <string>aggressively</string>
+        <key>agressor</key>
+        <string>aggressor</string>
+        <key>agricuture</key>
+        <string>agriculture</string>
+        <key>agrieved</key>
+        <string>aggrieved</string>
+        <key>ahev</key>
+        <string>have</string>
+        <key>ahppen</key>
+        <string>happen</string>
+        <key>ahve</key>
+        <string>have</string>
+        <key>aicraft</key>
+        <string>aircraft</string>
+        <key>aiport</key>
+        <string>airport</string>
+        <key>airbourne</key>
+        <string>airborne</string>
+        <key>aircaft</key>
+        <string>aircraft</string>
+        <key>aircrafts</key>
+        <string>aircraft</string>
+        <key>airporta</key>
+        <string>airports</string>
+        <key>airrcraft</key>
+        <string>aircraft</string>
+        <key>aisian</key>
+        <string>asian</string>
+        <key>albiet</key>
+        <string>albeit</string>
+        <key>alchohol</key>
+        <string>alcohol</string>
+        <key>alchoholic</key>
+        <string>alcoholic</string>
+        <key>alchol</key>
+        <string>alcohol</string>
+        <key>alcholic</key>
+        <string>alcoholic</string>
+        <key>alcohal</key>
+        <string>alcohol</string>
+        <key>alcoholical</key>
+        <string>alcoholic</string>
+        <key>aledge</key>
+        <string>allege</string>
+        <key>aledged</key>
+        <string>alleged</string>
+        <key>aledges</key>
+        <string>alleges</string>
+        <key>alege</key>
+        <string>allege</string>
+        <key>aleged</key>
+        <string>alleged</string>
+        <key>alegience</key>
+        <string>allegiance</string>
+        <key>algebraical</key>
+        <string>algebraic</string>
+        <key>algorhitms</key>
+        <string>algorithms</string>
+        <key>algoritm</key>
+        <string>algorithm</string>
+        <key>algoritms</key>
+        <string>algorithms</string>
+        <key>alientating</key>
+        <string>alienating</string>
+        <key>alledge</key>
+        <string>allege</string>
+        <key>alledged</key>
+        <string>alleged</string>
+        <key>alledgedly</key>
+        <string>allegedly</string>
+        <key>alledges</key>
+        <string>alleges</string>
+        <key>allegedely</key>
+        <string>allegedly</string>
+        <key>allegedy</key>
+        <string>allegedly</string>
+        <key>allegely</key>
+        <string>allegedly</string>
+        <key>allegence</key>
+        <string>allegiance</string>
+        <key>allegience</key>
+        <string>allegiance</string>
+        <key>allign</key>
+        <string>align</string>
+        <key>alligned</key>
+        <string>aligned</string>
+        <key>alliviate</key>
+        <string>alleviate</string>
+        <key>allopone</key>
+        <string>allophone</string>
+        <key>allopones</key>
+        <string>allophones</string>
+        <key>allready</key>
+        <string>already</string>
+        <key>allthough</key>
+        <string>although</string>
+        <key>alltime</key>
+        <string>all-time</string>
+        <key>alltogether</key>
+        <string>altogether</string>
+        <key>almsot</key>
+        <string>almost</string>
+        <key>alochol</key>
+        <string>alcohol</string>
+        <key>alomst</key>
+        <string>almost</string>
+        <key>alot</key>
+        <string>a lot</string>
+        <key>alotted</key>
+        <string>allotted</string>
+        <key>alowed</key>
+        <string>allowed</string>
+        <key>alowing</key>
+        <string>allowing</string>
+        <key>alreayd</key>
+        <string>already</string>
+        <key>alse</key>
+        <string>else</string>
+        <key>alsot</key>
+        <string>also</string>
+        <key>alternitives</key>
+        <string>alternatives</string>
+        <key>altho</key>
+        <string>although</string>
+        <key>althought</key>
+        <string>although</string>
+        <key>altough</key>
+        <string>although</string>
+        <key>alusion</key>
+        <string>allusion</string>
+        <key>alwasy</key>
+        <string>always</string>
+        <key>alwyas</key>
+        <string>always</string>
+        <key>amalgomated</key>
+        <string>amalgamated</string>
+        <key>amatuer</key>
+        <string>amateur</string>
+        <key>amature</key>
+        <string>armature</string>
+        <key>amendmant</key>
+        <string>amendment</string>
+        <key>amerliorate</key>
+        <string>ameliorate</string>
+        <key>amke</key>
+        <string>make</string>
+        <key>amking</key>
+        <string>making</string>
+        <key>ammend</key>
+        <string>amend</string>
+        <key>ammended</key>
+        <string>amended</string>
+        <key>ammendment</key>
+        <string>amendment</string>
+        <key>ammendments</key>
+        <string>amendments</string>
+        <key>ammount</key>
+        <string>amount</string>
+        <key>ammused</key>
+        <string>amused</string>
+        <key>amoung</key>
+        <string>among</string>
+        <key>amoungst</key>
+        <string>amongst</string>
+        <key>amung</key>
+        <string>among</string>
+        <key>amunition</key>
+        <string>ammunition</string>
+        <key>analagous</key>
+        <string>analogous</string>
+        <key>analitic</key>
+        <string>analytic</string>
+        <key>analogeous</key>
+        <string>analogous</string>
+        <key>anarchim</key>
+        <string>anarchism</string>
+        <key>anarchistm</key>
+        <string>anarchism</string>
+        <key>anbd</key>
+        <string>and</string>
+        <key>ancestory</key>
+        <string>ancestry</string>
+        <key>ancilliary</key>
+        <string>ancillary</string>
+        <key>androgenous</key>
+        <string>androgynous</string>
+        <key>androgeny</key>
+        <string>androgyny</string>
+        <key>anihilation</key>
+        <string>annihilation</string>
+        <key>aniversary</key>
+        <string>anniversary</string>
+        <key>annoint</key>
+        <string>anoint</string>
+        <key>annointed</key>
+        <string>anointed</string>
+        <key>annointing</key>
+        <string>anointing</string>
+        <key>annoints</key>
+        <string>anoints</string>
+        <key>annouced</key>
+        <string>announced</string>
+        <key>annualy</key>
+        <string>annually</string>
+        <key>annuled</key>
+        <string>annulled</string>
+        <key>anohter</key>
+        <string>another</string>
+        <key>anomolies</key>
+        <string>anomalies</string>
+        <key>anomolous</key>
+        <string>anomalous</string>
+        <key>anomoly</key>
+        <string>anomaly</string>
+        <key>anonimity</key>
+        <string>anonymity</string>
+        <key>anounced</key>
+        <string>announced</string>
+        <key>anouncement</key>
+        <string>announcement</string>
+        <key>ansalisation</key>
+        <string>nasalisation</string>
+        <key>ansalization</key>
+        <string>nasalization</string>
+        <key>ansestors</key>
+        <string>ancestors</string>
+        <key>antartic</key>
+        <string>antarctic</string>
+        <key>anthromorphization</key>
+        <string>anthropomorphization</string>
+        <key>anthropolgist</key>
+        <string>anthropologist</string>
+        <key>anthropolgy</key>
+        <string>anthropology</string>
+        <key>anual</key>
+        <string>annual</string>
+        <key>anulled</key>
+        <string>annulled</string>
+        <key>anwsered</key>
+        <string>answered</string>
+        <key>anyhwere</key>
+        <string>anywhere</string>
+        <key>anyother</key>
+        <string>any other</string>
+        <key>anytying</key>
+        <string>anything</string>
+        <key>aparent</key>
+        <string>apparent</string>
+        <key>aparment</key>
+        <string>apartment</string>
+        <key>apenines</key>
+        <string>apennines</string>
+        <key>aplication</key>
+        <string>application</string>
+        <key>aplied</key>
+        <string>applied</string>
+        <key>apolegetics</key>
+        <string>apologetics</string>
+        <key>apon</key>
+        <string>apron</string>
+        <key>apparant</key>
+        <string>apparent</string>
+        <key>apparantly</key>
+        <string>apparently</string>
+        <key>appart</key>
+        <string>apart</string>
+        <key>appartment</key>
+        <string>apartment</string>
+        <key>appartments</key>
+        <string>apartments</string>
+        <key>appealling</key>
+        <string>appealing</string>
+        <key>appeareance</key>
+        <string>appearance</string>
+        <key>appearence</key>
+        <string>appearance</string>
+        <key>appearences</key>
+        <string>appearances</string>
+        <key>apperance</key>
+        <string>appearance</string>
+        <key>apperances</key>
+        <string>appearances</string>
+        <key>appereance</key>
+        <string>appearance</string>
+        <key>appereances</key>
+        <string>appearances</string>
+        <key>applicaiton</key>
+        <string>application</string>
+        <key>applicaitons</key>
+        <string>applications</string>
+        <key>appologies</key>
+        <string>apologies</string>
+        <key>appology</key>
+        <string>apology</string>
+        <key>apprearance</key>
+        <string>appearance</string>
+        <key>apprieciate</key>
+        <string>appreciate</string>
+        <key>approachs</key>
+        <string>approaches</string>
+        <key>appropiate</key>
+        <string>appropriate</string>
+        <key>appropraite</key>
+        <string>appropriate</string>
+        <key>appropropiate</key>
+        <string>appropriate</string>
+        <key>approproximate</key>
+        <string>approximate</string>
+        <key>approxamately</key>
+        <string>approximately</string>
+        <key>approxiately</key>
+        <string>approximately</string>
+        <key>approximitely</key>
+        <string>approximately</string>
+        <key>aprehensive</key>
+        <string>apprehensive</string>
+        <key>apropriate</key>
+        <string>appropriate</string>
+        <key>aproximate</key>
+        <string>approximate</string>
+        <key>aproximately</key>
+        <string>approximately</string>
+        <key>aquaduct</key>
+        <string>aqueduct</string>
+        <key>aquaintance</key>
+        <string>acquaintance</string>
+        <key>aquainted</key>
+        <string>acquainted</string>
+        <key>aquiantance</key>
+        <string>acquaintance</string>
+        <key>aquire</key>
+        <string>acquire</string>
+        <key>aquired</key>
+        <string>acquired</string>
+        <key>aquiring</key>
+        <string>acquiring</string>
+        <key>aquisition</key>
+        <string>acquisition</string>
+        <key>aquitted</key>
+        <string>acquitted</string>
+        <key>aranged</key>
+        <string>arranged</string>
+        <key>arangement</key>
+        <string>arrangement</string>
+        <key>arbitarily</key>
+        <string>arbitrarily</string>
+        <key>arbitary</key>
+        <string>arbitrary</string>
+        <key>archaelogists</key>
+        <string>archaeologists</string>
+        <key>archaelogy</key>
+        <string>archaeology</string>
+        <key>archaoelogy</key>
+        <string>archaeology</string>
+        <key>archaology</key>
+        <string>archaeology</string>
+        <key>archeaologist</key>
+        <string>archaeologist</string>
+        <key>archeaologists</key>
+        <string>archaeologists</string>
+        <key>archetect</key>
+        <string>architect</string>
+        <key>archetects</key>
+        <string>architects</string>
+        <key>archetectural</key>
+        <string>architectural</string>
+        <key>archetecturally</key>
+        <string>architecturally</string>
+        <key>archetecture</key>
+        <string>architecture</string>
+        <key>archiac</key>
+        <string>archaic</string>
+        <key>archictect</key>
+        <string>architect</string>
+        <key>archimedian</key>
+        <string>archimedean</string>
+        <key>architecht</key>
+        <string>architect</string>
+        <key>architechturally</key>
+        <string>architecturally</string>
+        <key>architechture</key>
+        <string>architecture</string>
+        <key>architechtures</key>
+        <string>architectures</string>
+        <key>architectual</key>
+        <string>architectural</string>
+        <key>archtype</key>
+        <string>archetype</string>
+        <key>archtypes</key>
+        <string>archetypes</string>
+        <key>aready</key>
+        <string>already</string>
+        <key>areodynamics</key>
+        <string>aerodynamics</string>
+        <key>argubly</key>
+        <string>arguably</string>
+        <key>arguement</key>
+        <string>argument</string>
+        <key>arguements</key>
+        <string>arguments</string>
+        <key>arised</key>
+        <string>arose</string>
+        <key>arival</key>
+        <string>arrival</string>
+        <key>armamant</key>
+        <string>armament</string>
+        <key>armistace</key>
+        <string>armistice</string>
+        <key>arogant</key>
+        <string>arrogant</string>
+        <key>arogent</key>
+        <string>arrogant</string>
+        <key>aroud</key>
+        <string>around</string>
+        <key>arrangment</key>
+        <string>arrangement</string>
+        <key>arrangments</key>
+        <string>arrangements</string>
+        <key>arround</key>
+        <string>around</string>
+        <key>artical</key>
+        <string>article</string>
+        <key>artice</key>
+        <string>article</string>
+        <key>articel</key>
+        <string>article</string>
+        <key>artifical</key>
+        <string>artificial</string>
+        <key>artifically</key>
+        <string>artificially</string>
+        <key>artillary</key>
+        <string>artillery</string>
+        <key>arund</key>
+        <string>around</string>
+        <key>asetic</key>
+        <string>ascetic</string>
+        <key>asfar</key>
+        <string>as far</string>
+        <key>asign</key>
+        <string>assign</string>
+        <key>aslo</key>
+        <string>also</string>
+        <key>asociated</key>
+        <string>associated</string>
+        <key>asorbed</key>
+        <string>absorbed</string>
+        <key>asphyxation</key>
+        <string>asphyxiation</string>
+        <key>assasin</key>
+        <string>assassin</string>
+        <key>assasinate</key>
+        <string>assassinate</string>
+        <key>assasinated</key>
+        <string>assassinated</string>
+        <key>assasinates</key>
+        <string>assassinates</string>
+        <key>assasination</key>
+        <string>assassination</string>
+        <key>assasinations</key>
+        <string>assassinations</string>
+        <key>assasined</key>
+        <string>assassinated</string>
+        <key>assasins</key>
+        <string>assassins</string>
+        <key>assassintation</key>
+        <string>assassination</string>
+        <key>assemple</key>
+        <string>assemble</string>
+        <key>assertation</key>
+        <string>assertion</string>
+        <key>asside</key>
+        <string>aside</string>
+        <key>assisnate</key>
+        <string>assassinate</string>
+        <key>assit</key>
+        <string>assist</string>
+        <key>assitant</key>
+        <string>assistant</string>
+        <key>assocation</key>
+        <string>association</string>
+        <key>assoicate</key>
+        <string>associate</string>
+        <key>assoicated</key>
+        <string>associated</string>
+        <key>assoicates</key>
+        <string>associates</string>
+        <key>assosication</key>
+        <string>assassination</string>
+        <key>asssassans</key>
+        <string>assassins</string>
+        <key>assualt</key>
+        <string>assault</string>
+        <key>assualted</key>
+        <string>assaulted</string>
+        <key>assymetric</key>
+        <string>asymmetric</string>
+        <key>assymetrical</key>
+        <string>asymmetrical</string>
+        <key>asteriod</key>
+        <string>asteroid</string>
+        <key>asthetic</key>
+        <string>aesthetic</string>
+        <key>asthetical</key>
+        <string>aesthetical</string>
+        <key>asthetically</key>
+        <string>aesthetically</string>
+        <key>asume</key>
+        <string>assume</string>
+        <key>aswell</key>
+        <string>as well</string>
+        <key>atain</key>
+        <string>attain</string>
+        <key>atempting</key>
+        <string>attempting</string>
+        <key>atheistical</key>
+        <string>atheistic</string>
+        <key>athenean</key>
+        <string>athenian</string>
+        <key>atheneans</key>
+        <string>athenians</string>
+        <key>athiesm</key>
+        <string>atheism</string>
+        <key>athiest</key>
+        <string>atheist</string>
+        <key>atorney</key>
+        <string>attorney</string>
+        <key>atribute</key>
+        <string>attribute</string>
+        <key>atributed</key>
+        <string>attributed</string>
+        <key>atributes</key>
+        <string>attributes</string>
+        <key>attaindre</key>
+        <string>attainder</string>
+        <key>attemp</key>
+        <string>attempt</string>
+        <key>attemped</key>
+        <string>attempted</string>
+        <key>attemt</key>
+        <string>attempt</string>
+        <key>attemted</key>
+        <string>attempted</string>
+        <key>attemting</key>
+        <string>attempting</string>
+        <key>attemts</key>
+        <string>attempts</string>
+        <key>attendence</key>
+        <string>attendance</string>
+        <key>attendent</key>
+        <string>attendant</string>
+        <key>attendents</key>
+        <string>attendants</string>
+        <key>attened</key>
+        <string>attended</string>
+        <key>attension</key>
+        <string>attention</string>
+        <key>attitide</key>
+        <string>attitude</string>
+        <key>attributred</key>
+        <string>attributed</string>
+        <key>attrocities</key>
+        <string>atrocities</string>
+        <key>audeince</key>
+        <string>audience</string>
+        <key>auromated</key>
+        <string>automated</string>
+        <key>austrailia</key>
+        <string>Australia</string>
+        <key>austrailian</key>
+        <string>Australian</string>
+        <key>auther</key>
+        <string>author</string>
+        <key>authobiographic</key>
+        <string>autobiographic</string>
+        <key>authobiography</key>
+        <string>autobiography</string>
+        <key>authorative</key>
+        <string>authoritative</string>
+        <key>authorites</key>
+        <string>authorities</string>
+        <key>authorithy</key>
+        <string>authority</string>
+        <key>authoritiers</key>
+        <string>authorities</string>
+        <key>authoritive</key>
+        <string>authoritative</string>
+        <key>authrorities</key>
+        <string>authorities</string>
+        <key>autochtonous</key>
+        <string>autochthonous</string>
+        <key>autoctonous</key>
+        <string>autochthonous</string>
+        <key>automaticly</key>
+        <string>automatically</string>
+        <key>automibile</key>
+        <string>automobile</string>
+        <key>automonomous</key>
+        <string>autonomous</string>
+        <key>autor</key>
+        <string>author</string>
+        <key>autority</key>
+        <string>authority</string>
+        <key>auxilary</key>
+        <string>auxiliary</string>
+        <key>auxillaries</key>
+        <string>auxiliaries</string>
+        <key>auxillary</key>
+        <string>auxiliary</string>
+        <key>auxilliaries</key>
+        <string>auxiliaries</string>
+        <key>auxilliary</key>
+        <string>auxiliary</string>
+        <key>availabe</key>
+        <string> available</string>
+        <key>availablity</key>
+        <string>availability</string>
+        <key>availaible</key>
+        <string>available</string>
+        <key>availble</key>
+        <string>available</string>
+        <key>availiable</key>
+        <string>available</string>
+        <key>availible</key>
+        <string>available</string>
+        <key>avalable</key>
+        <string>available</string>
+        <key>avalance</key>
+        <string>avalanche</string>
+        <key>avaliable</key>
+        <string>available</string>
+        <key>avation</key>
+        <string>aviation</string>
+        <key>avengence</key>
+        <string>a vengeance</string>
+        <key>averageed</key>
+        <string>averaged</string>
+        <key>avilable</key>
+        <string>available</string>
+        <key>awared</key>
+        <string>awarded</string>
+        <key>awya</key>
+        <string>away</string>
+        <key>baceause</key>
+        <string>because</string>
+        <key>backgorund</key>
+        <string>background</string>
+        <key>backrounds</key>
+        <string>backgrounds</string>
+        <key>bakc</key>
+        <string>back</string>
+        <key>banannas</key>
+        <string>bananas</string>
+        <key>bandwith</key>
+        <string>bandwidth</string>
+        <key>bankrupcy</key>
+        <string>bankruptcy</string>
+        <key>banruptcy</key>
+        <string>bankruptcy</string>
+        <key>baout</key>
+        <string>about</string>
+        <key>basicaly</key>
+        <string>basically</string>
+        <key>basicly</key>
+        <string>basically</string>
+        <key>bcak</key>
+        <string>back</string>
+        <key>beachead</key>
+        <string>beachhead</string>
+        <key>beacuse</key>
+        <string>because</string>
+        <key>beastiality</key>
+        <string>bestiality</string>
+        <key>beatiful</key>
+        <string>beautiful</string>
+        <key>beaurocracy</key>
+        <string>bureaucracy</string>
+        <key>beaurocratic</key>
+        <string>bureaucratic</string>
+        <key>beautyfull</key>
+        <string>beautiful</string>
+        <key>becamae</key>
+        <string>became</string>
+        <key>becames</key>
+        <string>becomes</string>
+        <key>becasue</key>
+        <string>because</string>
+        <key>beccause</key>
+        <string>because</string>
+        <key>becomeing</key>
+        <string>becoming</string>
+        <key>becomming</key>
+        <string>becoming</string>
+        <key>becouse</key>
+        <string>because</string>
+        <key>becuase</key>
+        <string>because</string>
+        <key>bedore</key>
+        <string>before</string>
+        <key>befoer</key>
+        <string>before</string>
+        <key>beggin</key>
+        <string>begin</string>
+        <key>begginer</key>
+        <string>beginner</string>
+        <key>begginers</key>
+        <string>beginners</string>
+        <key>beggining</key>
+        <string>beginning</string>
+        <key>begginings</key>
+        <string>beginnings</string>
+        <key>beggins</key>
+        <string>begins</string>
+        <key>begining</key>
+        <string>beginning</string>
+        <key>beginnig</key>
+        <string>beginning</string>
+        <key>behavour</key>
+        <string>behavior</string>
+        <key>beleagured</key>
+        <string>beleaguered</string>
+        <key>beleif</key>
+        <string>belief</string>
+        <key>beleive</key>
+        <string>believe</string>
+        <key>beleived</key>
+        <string>believed</string>
+        <key>beleives</key>
+        <string>believes</string>
+        <key>beleiving</key>
+        <string>believing</string>
+        <key>beligum</key>
+        <string>belgium</string>
+        <key>belive</key>
+        <string>believe</string>
+        <key>belived</key>
+        <string>believed</string>
+        <key>belives</key>
+        <string>believes</string>
+        <key>belligerant</key>
+        <string>belligerent</string>
+        <key>bellweather</key>
+        <string>bellwether</string>
+        <key>bemusemnt</key>
+        <string>bemusement</string>
+        <key>beneficary</key>
+        <string>beneficiary</string>
+        <key>beng</key>
+        <string>being</string>
+        <key>benificial</key>
+        <string>beneficial</string>
+        <key>benifit</key>
+        <string>benefit</string>
+        <key>benifits</key>
+        <string>benefits</string>
+        <key>bergamont</key>
+        <string>bergamot</string>
+        <key>beseige</key>
+        <string>besiege</string>
+        <key>beseiged</key>
+        <string>besieged</string>
+        <key>beseiging</key>
+        <string>besieging</string>
+        <key>betwen</key>
+        <string>between</string>
+        <key>beween</key>
+        <string>between</string>
+        <key>bewteen</key>
+        <string>between</string>
+        <key>bilateraly</key>
+        <string>bilaterally</string>
+        <key>billingualism</key>
+        <string>bilingualism</string>
+        <key>binominal</key>
+        <string>binomial</string>
+        <key>bizzare</key>
+        <string>bizarre</string>
+        <key>blaim</key>
+        <string>blame</string>
+        <key>blaimed</key>
+        <string>blamed</string>
+        <key>blessure</key>
+        <string>blessing</string>
+        <key>bodydbuilder</key>
+        <string>bodybuilder</string>
+        <key>bombardement</key>
+        <string>bombardment</string>
+        <key>bombarment</key>
+        <string>bombardment</string>
+        <key>bondary</key>
+        <string>boundary</string>
+        <key>borke</key>
+        <string>broke</string>
+        <key>boundry</key>
+        <string>boundary</string>
+        <key>bouyancy</key>
+        <string>buoyancy</string>
+        <key>bouyant</key>
+        <string>buoyant</string>
+        <key>boyant</key>
+        <string>buoyant</string>
+        <key>breakthough</key>
+        <string>breakthrough</string>
+        <key>breakthroughts</key>
+        <string>breakthroughs</string>
+        <key>breif</key>
+        <string>brief</string>
+        <key>breifly</key>
+        <string>briefly</string>
+        <key>brethen</key>
+        <string>brethren</string>
+        <key>bretheren</key>
+        <string>brethren</string>
+        <key>briliant</key>
+        <string>brilliant</string>
+        <key>brillant</key>
+        <string>brilliant</string>
+        <key>brimestone</key>
+        <string>brimstone</string>
+        <key>broacasted</key>
+        <string>broadcast</string>
+        <key>broadacasting</key>
+        <string>broadcasting</string>
+        <key>broady</key>
+        <string>broadly</string>
+        <key>buisness</key>
+        <string>business</string>
+        <key>buisnessman</key>
+        <string>businessman</string>
+        <key>buoancy</key>
+        <string>buoyancy</string>
+        <key>burried</key>
+        <string>buried</string>
+        <key>busineses</key>
+        <string>businesses</string>
+        <key>busness</key>
+        <string>business</string>
+        <key>bussiness</key>
+        <string>business</string>
+        <key>caculater</key>
+        <string>calculator</string>
+        <key>cacuses</key>
+        <string>caucuses</string>
+        <key>cahracters</key>
+        <string>characters</string>
+        <key>calaber</key>
+        <string>caliber</string>
+        <key>calculater</key>
+        <string>calculator</string>
+        <key>calculs</key>
+        <string>calculus</string>
+        <key>calenders</key>
+        <string>calendars</string>
+        <key>caligraphy</key>
+        <string>calligraphy</string>
+        <key>caluclate</key>
+        <string>calculate</string>
+        <key>caluclated</key>
+        <string>calculated</string>
+        <key>caluculate</key>
+        <string>calculate</string>
+        <key>caluculated</key>
+        <string>calculated</string>
+        <key>calulate</key>
+        <string>calculate</string>
+        <key>calulated</key>
+        <string>calculated</string>
+        <key>calulater</key>
+        <string>calculator</string>
+        <key>camoflage</key>
+        <string>camouflage</string>
+        <key>campain</key>
+        <string>campaign</string>
+        <key>campains</key>
+        <string>campaigns</string>
+        <key>candadate</key>
+        <string>candidate</string>
+        <key>candiate</key>
+        <string>candidate</string>
+        <key>candidiate</key>
+        <string>candidate</string>
+        <key>cannister</key>
+        <string>canister</string>
+        <key>cannisters</key>
+        <string>canisters</string>
+        <key>cannnot</key>
+        <string>cannot</string>
+        <key>cannonical</key>
+        <string>canonical</string>
+        <key>cannotation</key>
+        <string>connotation</string>
+        <key>cannotations</key>
+        <string>connotations</string>
+        <key>cant</key>
+        <string>can&apos;t</string>
+        <key>caost</key>
+        <string>coast</string>
+        <key>caperbility</key>
+        <string>capability</string>
+        <key>capible</key>
+        <string>capable</string>
+        <key>captial</key>
+        <string>capital</string>
+        <key>captued</key>
+        <string>captured</string>
+        <key>capturd</key>
+        <string>captured</string>
+        <key>carachter</key>
+        <string>character</string>
+        <key>caracterized</key>
+        <string>characterized</string>
+        <key>carcas</key>
+        <string>carcass</string>
+        <key>carefull</key>
+        <string>careful</string>
+        <key>careing</key>
+        <string>caring</string>
+        <key>carismatic</key>
+        <string>charismatic</string>
+        <key>carnege</key>
+        <string>carnage</string>
+        <key>carnige</key>
+        <string>carnage</string>
+        <key>carniverous</key>
+        <string>carnivorous</string>
+        <key>carreer</key>
+        <string>career</string>
+        <key>carrers</key>
+        <string>careers</string>
+        <key>cartdridge</key>
+        <string>cartridge</string>
+        <key>carthographer</key>
+        <string>cartographer</string>
+        <key>cartilege</key>
+        <string>cartilage</string>
+        <key>cartilidge</key>
+        <string>cartilage</string>
+        <key>cartrige</key>
+        <string>cartridge</string>
+        <key>casette</key>
+        <string>cassette</string>
+        <key>casion</key>
+        <string>caisson</string>
+        <key>cassawory</key>
+        <string>cassowary</string>
+        <key>cassowarry</key>
+        <string>cassowary</string>
+        <key>casulaties</key>
+        <string>casualties</string>
+        <key>casulaty</key>
+        <string>casualty</string>
+        <key>catagories</key>
+        <string>categories</string>
+        <key>catagorized</key>
+        <string>categorized</string>
+        <key>catagory</key>
+        <string>category</string>
+        <key>catapillar</key>
+        <string>caterpillar</string>
+        <key>catapillars</key>
+        <string>caterpillars</string>
+        <key>catapiller</key>
+        <string>caterpillar</string>
+        <key>catapillers</key>
+        <string>caterpillars</string>
+        <key>catepillar</key>
+        <string>caterpillar</string>
+        <key>catepillars</key>
+        <string>caterpillars</string>
+        <key>catergorize</key>
+        <string>categorize</string>
+        <key>catergorized</key>
+        <string>categorized</string>
+        <key>caterpilar</key>
+        <string>caterpillar</string>
+        <key>caterpilars</key>
+        <string>caterpillars</string>
+        <key>caterpiller</key>
+        <string>caterpillar</string>
+        <key>caterpillers</key>
+        <string>caterpillars</string>
+        <key>cathlic</key>
+        <string>catholic</string>
+        <key>catholocism</key>
+        <string>catholicism</string>
+        <key>catterpilar</key>
+        <string>caterpillar</string>
+        <key>catterpilars</key>
+        <string>caterpillars</string>
+        <key>catterpillar</key>
+        <string>caterpillar</string>
+        <key>catterpillars</key>
+        <string>caterpillars</string>
+        <key>cattleship</key>
+        <string>battleship</string>
+        <key>causalities</key>
+        <string>casualties</string>
+        <key>cellpading</key>
+        <string>cellpadding</string>
+        <key>cementary</key>
+        <string>cemetery</string>
+        <key>cemetarey</key>
+        <string>cemetery</string>
+        <key>cemetaries</key>
+        <string>cemeteries</string>
+        <key>cemetary</key>
+        <string>cemetery</string>
+        <key>cencus</key>
+        <string>census</string>
+        <key>censur</key>
+        <string>censor</string>
+        <key>cententenial</key>
+        <string>centennial</string>
+        <key>centruies</key>
+        <string>centuries</string>
+        <key>centruy</key>
+        <string>century</string>
+        <key>ceratin</key>
+        <string>certain</string>
+        <key>cerimonial</key>
+        <string>ceremonial</string>
+        <key>cerimonies</key>
+        <string>ceremonies</string>
+        <key>cerimonious</key>
+        <string>ceremonious</string>
+        <key>cerimony</key>
+        <string>ceremony</string>
+        <key>ceromony</key>
+        <string>ceremony</string>
+        <key>certainity</key>
+        <string>certainty</string>
+        <key>certian</key>
+        <string>certain</string>
+        <key>chalenging</key>
+        <string>challenging</string>
+        <key>challange</key>
+        <string>challenge</string>
+        <key>challanged</key>
+        <string>challenged</string>
+        <key>challege</key>
+        <string>challenge</string>
+        <key>changable</key>
+        <string>changeable</string>
+        <key>charachter</key>
+        <string>character</string>
+        <key>charachters</key>
+        <string>characters</string>
+        <key>charactersistic</key>
+        <string>characteristic</string>
+        <key>charactor</key>
+        <string>character </string>
+        <key>charactors</key>
+        <string>characters</string>
+        <key>charasmatic</key>
+        <string>charismatic</string>
+        <key>charaterized</key>
+        <string>characterized</string>
+        <key>chariman</key>
+        <string>chairman</string>
+        <key>charistics</key>
+        <string>characteristics</string>
+        <key>cheif</key>
+        <string>chief</string>
+        <key>cheifs</key>
+        <string>chiefs</string>
+        <key>chemcial</key>
+        <string>chemical</string>
+        <key>chemcially</key>
+        <string>chemically</string>
+        <key>chemestry</key>
+        <string>chemistry</string>
+        <key>chemicaly</key>
+        <string>chemically</string>
+        <key>childbird</key>
+        <string>childbirth</string>
+        <key>childen</key>
+        <string>children</string>
+        <key>choosen</key>
+        <string>chosen</string>
+        <key>chracter</key>
+        <string>character</string>
+        <key>chuch</key>
+        <string>church</string>
+        <key>churchs</key>
+        <string>churches</string>
+        <key>circulaton</key>
+        <string>circulation</string>
+        <key>circumsicion</key>
+        <string>circumcision</string>
+        <key>circut</key>
+        <string>circuit</string>
+        <key>ciricuit</key>
+        <string>circuit</string>
+        <key>ciriculum</key>
+        <string>curriculum</string>
+        <key>civillian</key>
+        <string>civilian</string>
+        <key>claer</key>
+        <string>clear</string>
+        <key>claerer</key>
+        <string>clearer</string>
+        <key>claerly</key>
+        <string>clearly</string>
+        <key>claimes</key>
+        <string>claims</string>
+        <key>clas</key>
+        <string>class</string>
+        <key>clasic</key>
+        <string>classic</string>
+        <key>clasical</key>
+        <string>classical</string>
+        <key>clasically</key>
+        <string>classically</string>
+        <key>cleareance</key>
+        <string>clearance</string>
+        <key>clera</key>
+        <string>clear</string>
+        <key>clincial</key>
+        <string>clinical</string>
+        <key>clinicaly</key>
+        <string>clinically</string>
+        <key>cmo</key>
+        <string>com</string>
+        <key>cmoputer</key>
+        <string>computer</string>
+        <key>co-incided</key>
+        <string>coincided</string>
+        <key>coctail</key>
+        <string>cocktail</string>
+        <key>coform</key>
+        <string>conform</string>
+        <key>cognizent</key>
+        <string>cognizant</string>
+        <key>coincedentally</key>
+        <string>coincidentally</string>
+        <key>colaborations</key>
+        <string>collaborations</string>
+        <key>colateral</key>
+        <string>collateral</string>
+        <key>colelctive</key>
+        <string>collective</string>
+        <key>collaberative</key>
+        <string>collaborative</string>
+        <key>collecton</key>
+        <string>collection</string>
+        <key>collegue</key>
+        <string>colleague</string>
+        <key>collegues</key>
+        <string>colleagues</string>
+        <key>collonade</key>
+        <string>colonnade</string>
+        <key>collonies</key>
+        <string>colonies</string>
+        <key>collony</key>
+        <string>colony </string>
+        <key>collosal</key>
+        <string>colossal</string>
+        <key>colonizators</key>
+        <string>colonizers</string>
+        <key>comander</key>
+        <string>commander</string>
+        <key>comando</key>
+        <string>commando</string>
+        <key>comandos</key>
+        <string>commandos</string>
+        <key>comany</key>
+        <string>company</string>
+        <key>comapany</key>
+        <string>company</string>
+        <key>comback</key>
+        <string>comeback</string>
+        <key>combanations</key>
+        <string>combinations</string>
+        <key>combinatins</key>
+        <string>combinations</string>
+        <key>combusion</key>
+        <string>combustion</string>
+        <key>comdemnation</key>
+        <string>condemnation</string>
+        <key>comemmorates</key>
+        <string>commemorates</string>
+        <key>comemoretion</key>
+        <string>commemoration</string>
+        <key>comision</key>
+        <string>commission</string>
+        <key>comisioned</key>
+        <string>commissioned</string>
+        <key>comisioner</key>
+        <string>commissioner</string>
+        <key>comisioning</key>
+        <string>commissioning</string>
+        <key>comisions</key>
+        <string>commissions</string>
+        <key>comission</key>
+        <string>commission</string>
+        <key>comissioned</key>
+        <string>commissioned</string>
+        <key>comissioner</key>
+        <string>commissioner</string>
+        <key>comissioning</key>
+        <string>commissioning</string>
+        <key>comissions</key>
+        <string>commissions</string>
+        <key>comited</key>
+        <string>committed</string>
+        <key>comiting</key>
+        <string>committing</string>
+        <key>comitted</key>
+        <string>committed</string>
+        <key>comittee</key>
+        <string>committee</string>
+        <key>comitting</key>
+        <string>committing</string>
+        <key>commandoes</key>
+        <string>commandos</string>
+        <key>commedic</key>
+        <string>comedic</string>
+        <key>commemerative</key>
+        <string>commemorative</string>
+        <key>commemmorate</key>
+        <string>commemorate</string>
+        <key>commemmorating</key>
+        <string>commemorating</string>
+        <key>commerical</key>
+        <string>commercial</string>
+        <key>commerically</key>
+        <string>commercially</string>
+        <key>commericial</key>
+        <string>commercial</string>
+        <key>commericially</key>
+        <string>commercially</string>
+        <key>commerorative</key>
+        <string>commemorative</string>
+        <key>comming</key>
+        <string>coming</string>
+        <key>comminication</key>
+        <string>communication</string>
+        <key>commision</key>
+        <string>commission</string>
+        <key>commisioned</key>
+        <string>commissioned</string>
+        <key>commisioner</key>
+        <string>commissioner</string>
+        <key>commisioning</key>
+        <string>commissioning</string>
+        <key>commisions</key>
+        <string>commissions</string>
+        <key>commited</key>
+        <string>committed</string>
+        <key>commitee</key>
+        <string>committee</string>
+        <key>commiting</key>
+        <string>committing</string>
+        <key>committe</key>
+        <string>committee</string>
+        <key>committment</key>
+        <string>commitment</string>
+        <key>committments</key>
+        <string>commitments</string>
+        <key>commmemorated</key>
+        <string>commemorated</string>
+        <key>commongly</key>
+        <string>commonly</string>
+        <key>commonweath</key>
+        <string>commonwealth</string>
+        <key>commuications</key>
+        <string>communications</string>
+        <key>commuinications</key>
+        <string>communications</string>
+        <key>communciation</key>
+        <string>communication</string>
+        <key>communiation</key>
+        <string>communication</string>
+        <key>communites</key>
+        <string>communities</string>
+        <key>compability</key>
+        <string>compatibility</string>
+        <key>comparision</key>
+        <string>comparison</string>
+        <key>comparisions</key>
+        <string>comparisons</string>
+        <key>comparitive</key>
+        <string>comparative</string>
+        <key>comparitively</key>
+        <string>comparatively</string>
+        <key>compatabilities</key>
+        <string>compatibilities</string>
+        <key>compatability</key>
+        <string>compatibility</string>
+        <key>compatable</key>
+        <string>compatible</string>
+        <key>compatablities</key>
+        <string>compatibilities</string>
+        <key>compatablity</key>
+        <string>compatibility</string>
+        <key>compatiable</key>
+        <string>compatible</string>
+        <key>compatiblities</key>
+        <string>compatibilities</string>
+        <key>compatiblity</key>
+        <string>compatibility</string>
+        <key>compeitions</key>
+        <string>competitions</string>
+        <key>compensantion</key>
+        <string>compensation</string>
+        <key>competance</key>
+        <string>competence</string>
+        <key>competant</key>
+        <string>competent</string>
+        <key>competative</key>
+        <string>competitive</string>
+        <key>competion</key>
+        <string>competition</string>
+        <key>competitiion</key>
+        <string>competition</string>
+        <key>competive</key>
+        <string>competitive</string>
+        <key>competiveness</key>
+        <string>competitiveness</string>
+        <key>comphrehensive</key>
+        <string>comprehensive</string>
+        <key>compitent</key>
+        <string>competent</string>
+        <key>completedthe</key>
+        <string>completed the</string>
+        <key>completelyl</key>
+        <string>completely</string>
+        <key>completetion</key>
+        <string>completion</string>
+        <key>complier</key>
+        <string>compiler</string>
+        <key>componant</key>
+        <string>component</string>
+        <key>comprable</key>
+        <string>comparable</string>
+        <key>comprimise</key>
+        <string>compromise</string>
+        <key>compulsary</key>
+        <string>compulsory</string>
+        <key>compulsery</key>
+        <string>compulsory</string>
+        <key>computarized</key>
+        <string>computerized</string>
+        <key>concensus</key>
+        <string>consensus</string>
+        <key>concider</key>
+        <string>consider</string>
+        <key>concidered</key>
+        <string>considered</string>
+        <key>concidering</key>
+        <string>considering</string>
+        <key>conciders</key>
+        <string>considers</string>
+        <key>concieted</key>
+        <string>conceited</string>
+        <key>concieved</key>
+        <string>conceived</string>
+        <key>concious</key>
+        <string>conscious</string>
+        <key>conciously</key>
+        <string>consciously</string>
+        <key>conciousness</key>
+        <string>consciousness</string>
+        <key>condamned</key>
+        <string>condemned</string>
+        <key>condemmed</key>
+        <string>condemned</string>
+        <key>condidtion</key>
+        <string>condition</string>
+        <key>condidtions</key>
+        <string>conditions</string>
+        <key>conditionsof</key>
+        <string>conditions of</string>
+        <key>conected</key>
+        <string>connected</string>
+        <key>conection</key>
+        <string>connection</string>
+        <key>conesencus</key>
+        <string>consensus</string>
+        <key>confidental</key>
+        <string>confidential</string>
+        <key>confidentally</key>
+        <string>confidentially</string>
+        <key>confids</key>
+        <string>confides</string>
+        <key>configureable</key>
+        <string>configurable</string>
+        <key>confortable</key>
+        <string>comfortable</string>
+        <key>congradulations</key>
+        <string>congratulations</string>
+        <key>congresional</key>
+        <string>congressional</string>
+        <key>conived</key>
+        <string>connived</string>
+        <key>conjecutre</key>
+        <string>conjecture</string>
+        <key>conjuction</key>
+        <string>conjunction</string>
+        <key>conotations</key>
+        <string>connotations</string>
+        <key>conquerd</key>
+        <string>conquered</string>
+        <key>conquerer</key>
+        <string>conqueror</string>
+        <key>conquerers</key>
+        <string>conquerors</string>
+        <key>conqured</key>
+        <string>conquered</string>
+        <key>conscent</key>
+        <string>consent</string>
+        <key>consciouness</key>
+        <string>consciousness</string>
+        <key>consdider</key>
+        <string>consider</string>
+        <key>consdidered</key>
+        <string>considered</string>
+        <key>consdiered</key>
+        <string>considered</string>
+        <key>consectutive</key>
+        <string>consecutive</string>
+        <key>consenquently</key>
+        <string>consequently</string>
+        <key>consentrate</key>
+        <string>concentrate</string>
+        <key>consentrated</key>
+        <string>concentrated</string>
+        <key>consentrates</key>
+        <string>concentrates</string>
+        <key>consept</key>
+        <string>concept</string>
+        <key>consequentually</key>
+        <string>consequently</string>
+        <key>consequeseces</key>
+        <string>consequences</string>
+        <key>consern</key>
+        <string>concern</string>
+        <key>conserned</key>
+        <string>concerned</string>
+        <key>conserning</key>
+        <string>concerning</string>
+        <key>conservitive</key>
+        <string>conservative</string>
+        <key>consiciousness</key>
+        <string>consciousness</string>
+        <key>consicousness</key>
+        <string>consciousness</string>
+        <key>considerd</key>
+        <string>considered</string>
+        <key>consideres</key>
+        <string>considered</string>
+        <key>consious</key>
+        <string>conscious</string>
+        <key>consistant</key>
+        <string>consistent</string>
+        <key>consistantly</key>
+        <string>consistently</string>
+        <key>consituencies</key>
+        <string>constituencies</string>
+        <key>consituency</key>
+        <string>constituency</string>
+        <key>consituted</key>
+        <string>constituted</string>
+        <key>consitution</key>
+        <string>constitution</string>
+        <key>consitutional</key>
+        <string>constitutional</string>
+        <key>consolodate</key>
+        <string>consolidate</string>
+        <key>consolodated</key>
+        <string>consolidated</string>
+        <key>consonent</key>
+        <string>consonant</string>
+        <key>consonents</key>
+        <string>consonants</string>
+        <key>consorcium</key>
+        <string>consortium</string>
+        <key>conspiracys</key>
+        <string>conspiracies</string>
+        <key>conspiriator</key>
+        <string>conspirator</string>
+        <key>constaints</key>
+        <string>constraints</string>
+        <key>constanly</key>
+        <string>constantly</string>
+        <key>constarnation</key>
+        <string>consternation</string>
+        <key>constatn</key>
+        <string>constant</string>
+        <key>constinually</key>
+        <string>continually</string>
+        <key>constituant</key>
+        <string>constituent</string>
+        <key>constituants</key>
+        <string>constituents</string>
+        <key>constituion</key>
+        <string>constitution</string>
+        <key>constituional</key>
+        <string>constitutional</string>
+        <key>consttruction</key>
+        <string>construction</string>
+        <key>constuction</key>
+        <string>construction</string>
+        <key>consulant</key>
+        <string>consultant</string>
+        <key>consumate</key>
+        <string>consummate</string>
+        <key>consumated</key>
+        <string>consummated</string>
+        <key>contaiminate</key>
+        <string>contaminate</string>
+        <key>containes</key>
+        <string>contains</string>
+        <key>contamporaries</key>
+        <string>contemporaries</string>
+        <key>contamporary</key>
+        <string>contemporary</string>
+        <key>contempoary</key>
+        <string>contemporary</string>
+        <key>contemporaneus</key>
+        <string>contemporaneous</string>
+        <key>contempory</key>
+        <string>contemporary</string>
+        <key>contendor</key>
+        <string>contender</string>
+        <key>contibute</key>
+        <string>contribute </string>
+        <key>contibuted</key>
+        <string>contributed </string>
+        <key>contibutes</key>
+        <string>contributes </string>
+        <key>contigent</key>
+        <string>contingent</string>
+        <key>contined</key>
+        <string>continued</string>
+        <key>continous</key>
+        <string>continuous</string>
+        <key>continously</key>
+        <string>continuously</string>
+        <key>continueing</key>
+        <string>continuing</string>
+        <key>contravercial</key>
+        <string>controversial</string>
+        <key>contraversy</key>
+        <string>controversy</string>
+        <key>contributer</key>
+        <string>contributor</string>
+        <key>contributers</key>
+        <string>contributors</string>
+        <key>contritutions</key>
+        <string>contributions</string>
+        <key>controled</key>
+        <string>controlled</string>
+        <key>controling</key>
+        <string>controlling</string>
+        <key>controll</key>
+        <string>control</string>
+        <key>controlls</key>
+        <string>controls</string>
+        <key>controvercial</key>
+        <string>controversial</string>
+        <key>controvercy</key>
+        <string>controversy</string>
+        <key>controveries</key>
+        <string>controversies</string>
+        <key>controversal</key>
+        <string>controversial</string>
+        <key>controversey</key>
+        <string>controversy</string>
+        <key>controvertial</key>
+        <string>controversial</string>
+        <key>controvery</key>
+        <string>controversy</string>
+        <key>contruction</key>
+        <string>construction</string>
+        <key>conveinent</key>
+        <string>convenient</string>
+        <key>convenant</key>
+        <string>covenant</string>
+        <key>convential</key>
+        <string>conventional</string>
+        <key>convertables</key>
+        <string>convertibles</string>
+        <key>convertion</key>
+        <string>conversion</string>
+        <key>conveyer</key>
+        <string>conveyor</string>
+        <key>conviced</key>
+        <string>convinced</string>
+        <key>convienient</key>
+        <string>convenient</string>
+        <key>coordiantion</key>
+        <string>coordination</string>
+        <key>coorperations</key>
+        <string>corporations</string>
+        <key>copmetitors</key>
+        <string>competitors</string>
+        <key>coputer</key>
+        <string>computer</string>
+        <key>copywrite</key>
+        <string>copyright</string>
+        <key>coridal</key>
+        <string>cordial</string>
+        <key>cornmitted</key>
+        <string>committed</string>
+        <key>corosion</key>
+        <string>corrosion</string>
+        <key>corparate</key>
+        <string>corporate</string>
+        <key>corperations</key>
+        <string>corporations</string>
+        <key>correcters</key>
+        <string>correctors</string>
+        <key>correponding</key>
+        <string>corresponding</string>
+        <key>correposding</key>
+        <string>corresponding</string>
+        <key>correspondant</key>
+        <string>correspondent</string>
+        <key>correspondants</key>
+        <string>correspondents</string>
+        <key>corridoors</key>
+        <string>corridors</string>
+        <key>corrispond</key>
+        <string>correspond</string>
+        <key>corrispondant</key>
+        <string>correspondent</string>
+        <key>corrispondants</key>
+        <string>correspondents</string>
+        <key>corrisponded</key>
+        <string>corresponded</string>
+        <key>corrisponding</key>
+        <string>corresponding</string>
+        <key>corrisponds</key>
+        <string>corresponds</string>
+        <key>costitution</key>
+        <string>constitution</string>
+        <key>coucil</key>
+        <string>council</string>
+        <key>counries</key>
+        <string>countries</string>
+        <key>countains</key>
+        <string>contains</string>
+        <key>countires</key>
+        <string>countries</string>
+        <key>coururier</key>
+        <string>courier</string>
+        <key>coverted</key>
+        <string>converted</string>
+        <key>cpoy</key>
+        <string>copy</string>
+        <key>creaeted</key>
+        <string>created</string>
+        <key>creedence</key>
+        <string>credence</string>
+        <key>critereon</key>
+        <string>criterion</string>
+        <key>criterias</key>
+        <string>criteria</string>
+        <key>criticists</key>
+        <string>critics</string>
+        <key>critising</key>
+        <string>criticising</string>
+        <key>critisising</key>
+        <string>criticising</string>
+        <key>critisism</key>
+        <string>criticism</string>
+        <key>critisisms</key>
+        <string>criticisms</string>
+        <key>critisize</key>
+        <string>criticise</string>
+        <key>critisized</key>
+        <string>criticised</string>
+        <key>critisizes</key>
+        <string>criticises</string>
+        <key>critisizing</key>
+        <string>criticising</string>
+        <key>critized</key>
+        <string>criticized</string>
+        <key>critizing</key>
+        <string>criticizing</string>
+        <key>crockodiles</key>
+        <string>crocodiles</string>
+        <key>crowm</key>
+        <string>crown</string>
+        <key>crtical</key>
+        <string>critical</string>
+        <key>crticised</key>
+        <string>criticised</string>
+        <key>crucifiction</key>
+        <string>crucifixion</string>
+        <key>crusies</key>
+        <string>cruises</string>
+        <key>crystalisation</key>
+        <string>crystallisation</string>
+        <key>culiminating</key>
+        <string>culminating</string>
+        <key>cumulatative</key>
+        <string>cumulative</string>
+        <key>curch</key>
+        <string>church</string>
+        <key>curcuit</key>
+        <string>circuit</string>
+        <key>currenly</key>
+        <string>currently</string>
+        <key>curriculem</key>
+        <string>curriculum</string>
+        <key>cxan</key>
+        <string>cyan</string>
+        <key>cyclinder</key>
+        <string>cylinder</string>
+        <key>dacquiri</key>
+        <string>daiquiri</string>
+        <key>dael</key>
+        <string>deal</string>
+        <key>dalmation</key>
+        <string>dalmatian</string>
+        <key>damenor</key>
+        <string>demeanor</string>
+        <key>dammage</key>
+        <string>damage</string>
+        <key>daugher</key>
+        <string>daughter</string>
+        <key>debateable</key>
+        <string>debatable</string>
+        <key>decendant</key>
+        <string>descendant</string>
+        <key>decendants</key>
+        <string>descendants</string>
+        <key>decendent</key>
+        <string>descendant</string>
+        <key>decendents</key>
+        <string>descendants</string>
+        <key>decideable</key>
+        <string>decidable</string>
+        <key>decidely</key>
+        <string>decidedly</string>
+        <key>decieved</key>
+        <string>deceived</string>
+        <key>decison</key>
+        <string>decision</string>
+        <key>decomissioned</key>
+        <string>decommissioned</string>
+        <key>decomposit</key>
+        <string>decompose</string>
+        <key>decomposited</key>
+        <string>decomposed</string>
+        <key>decompositing</key>
+        <string>decomposing</string>
+        <key>decomposits</key>
+        <string>decomposes</string>
+        <key>decress</key>
+        <string>decrees</string>
+        <key>decribe</key>
+        <string>describe</string>
+        <key>decribed</key>
+        <string>described</string>
+        <key>decribes</key>
+        <string>describes</string>
+        <key>decribing</key>
+        <string>describing</string>
+        <key>dectect</key>
+        <string>detect</string>
+        <key>defendent</key>
+        <string>defendant</string>
+        <key>defendents</key>
+        <string>defendants</string>
+        <key>deffensively</key>
+        <string>defensively</string>
+        <key>deffine</key>
+        <string>define</string>
+        <key>deffined</key>
+        <string>defined</string>
+        <key>definance</key>
+        <string>defiance</string>
+        <key>definate</key>
+        <string>definite</string>
+        <key>definately</key>
+        <string>definitely</string>
+        <key>definatly</key>
+        <string>definitely</string>
+        <key>definetly</key>
+        <string>definitely</string>
+        <key>definining</key>
+        <string>defining</string>
+        <key>definit</key>
+        <string>definite</string>
+        <key>definitly</key>
+        <string>definitely</string>
+        <key>definiton</key>
+        <string>definition</string>
+        <key>defintion</key>
+        <string>definition</string>
+        <key>degrate</key>
+        <string>degrade</string>
+        <key>delagates</key>
+        <string>delegates</string>
+        <key>delapidated</key>
+        <string>dilapidated</string>
+        <key>delerious</key>
+        <string>delirious</string>
+        <key>delevopment</key>
+        <string>development</string>
+        <key>deliberatly</key>
+        <string>deliberately</string>
+        <key>delusionally</key>
+        <string>delusively</string>
+        <key>demenor</key>
+        <string>demeanor</string>
+        <key>demographical</key>
+        <string>demographic</string>
+        <key>demolision</key>
+        <string>demolition</string>
+        <key>demorcracy</key>
+        <string>democracy</string>
+        <key>demostration</key>
+        <string>demonstration</string>
+        <key>denegrating</key>
+        <string>denigrating</string>
+        <key>densly</key>
+        <string>densely</string>
+        <key>deparment</key>
+        <string>department</string>
+        <key>deparmental</key>
+        <string>departmental</string>
+        <key>deparments</key>
+        <string>departments</string>
+        <key>dependance</key>
+        <string>dependence</string>
+        <key>dependancy</key>
+        <string>dependency</string>
+        <key>dependant</key>
+        <string>dependent</string>
+        <key>deram</key>
+        <string>dream</string>
+        <key>deriviated</key>
+        <string>derived</string>
+        <key>derivitive</key>
+        <string>derivative</string>
+        <key>derogitory</key>
+        <string>derogatory</string>
+        <key>descendands</key>
+        <string>descendants</string>
+        <key>descibed</key>
+        <string>described</string>
+        <key>descision</key>
+        <string>decision</string>
+        <key>descisions</key>
+        <string>decisions</string>
+        <key>descriibes</key>
+        <string>describes</string>
+        <key>descripters</key>
+        <string>descriptors</string>
+        <key>descripton</key>
+        <string>description</string>
+        <key>desctruction</key>
+        <string>destruction</string>
+        <key>descuss</key>
+        <string>discuss</string>
+        <key>desgined</key>
+        <string>designed</string>
+        <key>deside</key>
+        <string>decide</string>
+        <key>desigining</key>
+        <string>designing</string>
+        <key>desinations</key>
+        <string>destinations</string>
+        <key>desintegrated</key>
+        <string>disintegrated</string>
+        <key>desintegration</key>
+        <string>disintegration</string>
+        <key>desireable</key>
+        <string>desirable</string>
+        <key>desitned</key>
+        <string>destined</string>
+        <key>desktiop</key>
+        <string>desktop</string>
+        <key>desorder</key>
+        <string>disorder</string>
+        <key>desoriented</key>
+        <string>disoriented</string>
+        <key>desparate</key>
+        <string>desperate</string>
+        <key>despict</key>
+        <string>depict</string>
+        <key>despiration</key>
+        <string>desperation</string>
+        <key>dessicated</key>
+        <string>desiccated</string>
+        <key>dessigned</key>
+        <string>designed</string>
+        <key>destablized</key>
+        <string>destabilized</string>
+        <key>destory</key>
+        <string>destroy</string>
+        <key>detailled</key>
+        <string>detailed</string>
+        <key>detatched</key>
+        <string>detached</string>
+        <key>deteoriated</key>
+        <string>deteriorated</string>
+        <key>deteriate</key>
+        <string>deteriorate</string>
+        <key>deterioriating</key>
+        <string>deteriorating</string>
+        <key>determinining</key>
+        <string>determining</string>
+        <key>detremental</key>
+        <string>detrimental</string>
+        <key>devasted</key>
+        <string>devastated</string>
+        <key>develope</key>
+        <string>develop</string>
+        <key>developement</key>
+        <string>development</string>
+        <key>developped</key>
+        <string>developed</string>
+        <key>develpment</key>
+        <string>development</string>
+        <key>devels</key>
+        <string>delves</string>
+        <key>devestated</key>
+        <string>devastated</string>
+        <key>devestating</key>
+        <string>devastating</string>
+        <key>devide</key>
+        <string>divide</string>
+        <key>devided</key>
+        <string>divided</string>
+        <key>devistating</key>
+        <string>devastating</string>
+        <key>devolopement</key>
+        <string>development</string>
+        <key>diablical</key>
+        <string>diabolical</string>
+        <key>diamons</key>
+        <string>diamonds</string>
+        <key>diaster</key>
+        <string>disaster</string>
+        <key>dichtomy</key>
+        <string>dichotomy</string>
+        <key>diconnects</key>
+        <string>disconnects</string>
+        <key>dicover</key>
+        <string>discover</string>
+        <key>dicovered</key>
+        <string>discovered</string>
+        <key>dicovering</key>
+        <string>discovering</string>
+        <key>dicovers</key>
+        <string>discovers</string>
+        <key>dicovery</key>
+        <string>discovery</string>
+        <key>dicussed</key>
+        <string>discussed</string>
+        <key>didnt</key>
+        <string>didn&apos;t</string>
+        <key>diea</key>
+        <string>idea</string>
+        <key>dieing</key>
+        <string>dying</string>
+        <key>dieties</key>
+        <string>deities</string>
+        <key>diety</key>
+        <string>deity</string>
+        <key>diferent</key>
+        <string>different</string>
+        <key>diferrent</key>
+        <string>different</string>
+        <key>differentiatiations</key>
+        <string>differentiations</string>
+        <key>differnt</key>
+        <string>different</string>
+        <key>difficulity</key>
+        <string>difficulty</string>
+        <key>diffrent</key>
+        <string>different</string>
+        <key>dificulties</key>
+        <string>difficulties</string>
+        <key>dificulty</key>
+        <string>difficulty</string>
+        <key>dimenions</key>
+        <string>dimensions</string>
+        <key>dimention</key>
+        <string>dimension</string>
+        <key>dimentional</key>
+        <string>dimensional</string>
+        <key>dimentions</key>
+        <string>dimensions</string>
+        <key>dimesnional</key>
+        <string>dimensional</string>
+        <key>diminuitive</key>
+        <string>diminutive</string>
+        <key>dimunitive</key>
+        <string>diminutive</string>
+        <key>diosese</key>
+        <string>diocese</string>
+        <key>diphtong</key>
+        <string>diphthong</string>
+        <key>diphtongs</key>
+        <string>diphthongs</string>
+        <key>diplomancy</key>
+        <string>diplomacy</string>
+        <key>dipthong</key>
+        <string>diphthong</string>
+        <key>dipthongs</key>
+        <string>diphthongs</string>
+        <key>dirived</key>
+        <string>derived</string>
+        <key>disagreeed</key>
+        <string>disagreed</string>
+        <key>disapeared</key>
+        <string>disappeared</string>
+        <key>disapointing</key>
+        <string>disappointing</string>
+        <key>disappearred</key>
+        <string>disappeared</string>
+        <key>disaproval</key>
+        <string>disapproval</string>
+        <key>disasterous</key>
+        <string>disastrous</string>
+        <key>disatisfaction</key>
+        <string>dissatisfaction</string>
+        <key>disatisfied</key>
+        <string>dissatisfied</string>
+        <key>disatrous</key>
+        <string>disastrous</string>
+        <key>discontentment</key>
+        <string>discontent</string>
+        <key>discribe</key>
+        <string>describe</string>
+        <key>discribed</key>
+        <string>described</string>
+        <key>discribes</key>
+        <string>describes</string>
+        <key>discribing</key>
+        <string>describing</string>
+        <key>disctinction</key>
+        <string>distinction</string>
+        <key>disctinctive</key>
+        <string>distinctive</string>
+        <key>disemination</key>
+        <string>dissemination</string>
+        <key>disenchanged</key>
+        <string>disenchanted</string>
+        <key>disiplined</key>
+        <string>disciplined</string>
+        <key>disobediance</key>
+        <string>disobedience</string>
+        <key>disobediant</key>
+        <string>disobedient</string>
+        <key>disolved</key>
+        <string>dissolved</string>
+        <key>disover</key>
+        <string>discover</string>
+        <key>dispair</key>
+        <string>despair</string>
+        <key>disparingly</key>
+        <string>disparagingly</string>
+        <key>dispence</key>
+        <string>dispense</string>
+        <key>dispenced</key>
+        <string>dispensed</string>
+        <key>dispencing</key>
+        <string>dispensing</string>
+        <key>dispicable</key>
+        <string>despicable</string>
+        <key>dispite</key>
+        <string>despite</string>
+        <key>dispostion</key>
+        <string>disposition</string>
+        <key>disproportiate</key>
+        <string>disproportionate</string>
+        <key>disputandem</key>
+        <string>disputandum</string>
+        <key>disricts</key>
+        <string>districts</string>
+        <key>dissagreement</key>
+        <string>disagreement</string>
+        <key>dissapear</key>
+        <string>disappear</string>
+        <key>dissapearance</key>
+        <string>disappearance</string>
+        <key>dissapeared</key>
+        <string>disappeared</string>
+        <key>dissapearing</key>
+        <string>disappearing</string>
+        <key>dissapears</key>
+        <string>disappears</string>
+        <key>dissappear</key>
+        <string>disappear</string>
+        <key>dissappears</key>
+        <string>disappears</string>
+        <key>dissappointed</key>
+        <string>disappointed</string>
+        <key>dissarray</key>
+        <string>disarray</string>
+        <key>dissobediance</key>
+        <string>disobedience</string>
+        <key>dissobediant</key>
+        <string>disobedient</string>
+        <key>dissobedience</key>
+        <string>disobedience</string>
+        <key>dissobedient</key>
+        <string>disobedient</string>
+        <key>distiction</key>
+        <string>distinction</string>
+        <key>distingish</key>
+        <string>distinguish</string>
+        <key>distingished</key>
+        <string>distinguished</string>
+        <key>distingishes</key>
+        <string>distinguishes</string>
+        <key>distingishing</key>
+        <string>distinguishing</string>
+        <key>distingquished</key>
+        <string>distinguished</string>
+        <key>distrubution</key>
+        <string>distribution</string>
+        <key>distruction</key>
+        <string>destruction</string>
+        <key>distructive</key>
+        <string>destructive</string>
+        <key>ditributed</key>
+        <string>distributed</string>
+        <key>diversed</key>
+        <string>diverged</string>
+        <key>divice</key>
+        <string>device</string>
+        <key>divison</key>
+        <string>division</string>
+        <key>divisons</key>
+        <string>divisions</string>
+        <key>doccument</key>
+        <string>document</string>
+        <key>doccumented</key>
+        <string>documented</string>
+        <key>doccuments</key>
+        <string>documents</string>
+        <key>docrines</key>
+        <string>doctrines</string>
+        <key>doctines</key>
+        <string>doctrines</string>
+        <key>documenatry</key>
+        <string>documentary</string>
+        <key>doens</key>
+        <string>does</string>
+        <key>doesnt</key>
+        <string>doesn&apos;t</string>
+        <key>doign</key>
+        <string>doing</string>
+        <key>dominaton</key>
+        <string>domination</string>
+        <key>dominent</key>
+        <string>dominant</string>
+        <key>dominiant</key>
+        <string>dominant</string>
+        <key>donig</key>
+        <string>doing</string>
+        <key>dont</key>
+        <string>don&apos;t</string>
+        <key>dosen&apos;t</key>
+        <string>doesn&apos;t</string>
+        <key>doub</key>
+        <string>doubt</string>
+        <key>doulbe</key>
+        <string>double</string>
+        <key>dowloads</key>
+        <string>downloads</string>
+        <key>dramtic</key>
+        <string>dramatic</string>
+        <key>draughtman</key>
+        <string>draughtsman</string>
+        <key>dreasm</key>
+        <string>dreams</string>
+        <key>driectly</key>
+        <string>directly</string>
+        <key>drnik</key>
+        <string>drink</string>
+        <key>druming</key>
+        <string>drumming</string>
+        <key>drummless</key>
+        <string>drumless</string>
+        <key>dupicate</key>
+        <string>duplicate</string>
+        <key>durig</key>
+        <string>during</string>
+        <key>durring</key>
+        <string>during</string>
+        <key>duting</key>
+        <string>during</string>
+        <key>dyas</key>
+        <string>dryas</string>
+        <key>eahc</key>
+        <string>each</string>
+        <key>ealier</key>
+        <string>earlier</string>
+        <key>earlies</key>
+        <string>earliest</string>
+        <key>earnt</key>
+        <string>earned</string>
+        <key>ecclectic</key>
+        <string>eclectic</string>
+        <key>eceonomy</key>
+        <string>economy</string>
+        <key>ecidious</key>
+        <string>deciduous</string>
+        <key>eclispe</key>
+        <string>eclipse</string>
+        <key>ecomonic</key>
+        <string>economic</string>
+        <key>ect</key>
+        <string>etc</string>
+        <key>eearly</key>
+        <string>early</string>
+        <key>efel</key>
+        <string>evil</string>
+        <key>effeciency</key>
+        <string>efficiency</string>
+        <key>effecient</key>
+        <string>efficient</string>
+        <key>effeciently</key>
+        <string>efficiently</string>
+        <key>efficency</key>
+        <string>efficiency</string>
+        <key>efficent</key>
+        <string>efficient</string>
+        <key>efficently</key>
+        <string>efficiently</string>
+        <key>efford</key>
+        <string>effort</string>
+        <key>effords</key>
+        <string>efforts</string>
+        <key>effulence</key>
+        <string>effluence</string>
+        <key>eigth</key>
+        <string>eight</string>
+        <key>eiter</key>
+        <string>either</string>
+        <key>elction</key>
+        <string>election</string>
+        <key>electic</key>
+        <string>electric</string>
+        <key>electon</key>
+        <string>electron</string>
+        <key>electrial</key>
+        <string>electrical</string>
+        <key>electricly</key>
+        <string>electrically</string>
+        <key>electricty</key>
+        <string>electricity</string>
+        <key>elementay</key>
+        <string>elementary</string>
+        <key>eleminated</key>
+        <string>eliminated</string>
+        <key>eleminating</key>
+        <string>eliminating</string>
+        <key>eles</key>
+        <string>eels</string>
+        <key>eletricity</key>
+        <string>electricity</string>
+        <key>elicided</key>
+        <string>elicited</string>
+        <key>eligable</key>
+        <string>eligible</string>
+        <key>elimentary</key>
+        <string>elementary</string>
+        <key>ellected</key>
+        <string>elected</string>
+        <key>elphant</key>
+        <string>elephant</string>
+        <key>embarass</key>
+        <string>embarrass</string>
+        <key>embarassed</key>
+        <string>embarrassed</string>
+        <key>embarassing</key>
+        <string>embarrassing</string>
+        <key>embarassment</key>
+        <string>embarrassment</string>
+        <key>embargos</key>
+        <string>embargoes</string>
+        <key>embarras</key>
+        <string>embarrass</string>
+        <key>embarrased</key>
+        <string>embarrassed</string>
+        <key>embarrasing</key>
+        <string>embarrassing</string>
+        <key>embarrasment</key>
+        <string>embarrassment</string>
+        <key>embezelled</key>
+        <string>embezzled</string>
+        <key>emblamatic</key>
+        <string>emblematic</string>
+        <key>eminate</key>
+        <string>emanate</string>
+        <key>eminated</key>
+        <string>emanated</string>
+        <key>emision</key>
+        <string>emission</string>
+        <key>emited</key>
+        <string>emitted</string>
+        <key>emiting</key>
+        <string>emitting</string>
+        <key>emition</key>
+        <string>emission</string>
+        <key>emmediately</key>
+        <string>immediately</string>
+        <key>emmigrated</key>
+        <string>immigrated</string>
+        <key>emminently</key>
+        <string>eminently</string>
+        <key>emmisaries</key>
+        <string>emissaries</string>
+        <key>emmisarries</key>
+        <string>emissaries</string>
+        <key>emmisarry</key>
+        <string>emissary</string>
+        <key>emmisary</key>
+        <string>emissary</string>
+        <key>emmision</key>
+        <string>emission</string>
+        <key>emmisions</key>
+        <string>emissions</string>
+        <key>emmited</key>
+        <string>emitted</string>
+        <key>emmiting</key>
+        <string>emitting</string>
+        <key>emmitted</key>
+        <string>emitted</string>
+        <key>emmitting</key>
+        <string>emitting</string>
+        <key>emnity</key>
+        <string>enmity</string>
+        <key>emperical</key>
+        <string>empirical</string>
+        <key>emphaised</key>
+        <string>emphasised</string>
+        <key>emphsis</key>
+        <string>emphasis</string>
+        <key>emphysyma</key>
+        <string>emphysema</string>
+        <key>emprisoned</key>
+        <string>imprisoned</string>
+        <key>enameld</key>
+        <string>enameled</string>
+        <key>enchancement</key>
+        <string>enhancement</string>
+        <key>encouraing</key>
+        <string>encouraging</string>
+        <key>encryptiion</key>
+        <string>encryption</string>
+        <key>encylopedia</key>
+        <string>encyclopedia</string>
+        <key>endevors</key>
+        <string>endeavors</string>
+        <key>endevour</key>
+        <string>endeavour</string>
+        <key>endig</key>
+        <string>ending</string>
+        <key>endolithes</key>
+        <string>endoliths</string>
+        <key>enduce</key>
+        <string>induce</string>
+        <key>ened</key>
+        <string>need</string>
+        <key>enflamed</key>
+        <string>inflamed</string>
+        <key>enforceing</key>
+        <string>enforcing</string>
+        <key>engagment</key>
+        <string>engagement</string>
+        <key>engeneer</key>
+        <string>engineer</string>
+        <key>engeneering</key>
+        <string>engineering</string>
+        <key>engieneer</key>
+        <string>engineer</string>
+        <key>engieneers</key>
+        <string>engineers</string>
+        <key>enlargment</key>
+        <string>enlargement</string>
+        <key>enlargments</key>
+        <string>enlargements</string>
+        <key>enourmous</key>
+        <string>enormous</string>
+        <key>enourmously</key>
+        <string>enormously</string>
+        <key>ensconsed</key>
+        <string>ensconced</string>
+        <key>entaglements</key>
+        <string>entanglements</string>
+        <key>enteratinment</key>
+        <string>entertainment</string>
+        <key>enthusiatic</key>
+        <string>enthusiastic</string>
+        <key>entitity</key>
+        <string>entity</string>
+        <key>entitlied</key>
+        <string>entitled</string>
+        <key>entrepeneur</key>
+        <string>entrepreneur</string>
+        <key>entrepeneurs</key>
+        <string>entrepreneurs</string>
+        <key>enviorment</key>
+        <string>environment</string>
+        <key>enviormental</key>
+        <string>environmental</string>
+        <key>enviormentally</key>
+        <string>environmentally</string>
+        <key>enviorments</key>
+        <string>environments</string>
+        <key>enviornment</key>
+        <string>environment</string>
+        <key>enviornmental</key>
+        <string>environmental</string>
+        <key>enviornmentalist</key>
+        <string>environmentalist</string>
+        <key>enviornmentally</key>
+        <string>environmentally</string>
+        <key>enviornments</key>
+        <string>environments</string>
+        <key>enviroment</key>
+        <string>environment</string>
+        <key>enviromental</key>
+        <string>environmental</string>
+        <key>enviromentalist</key>
+        <string>environmentalist</string>
+        <key>enviromentally</key>
+        <string>environmentally</string>
+        <key>enviroments</key>
+        <string>environments</string>
+        <key>envolutionary</key>
+        <string>evolutionary</string>
+        <key>envrionments</key>
+        <string>environments</string>
+        <key>enxt</key>
+        <string>next</string>
+        <key>epidsodes</key>
+        <string>episodes</string>
+        <key>epsiode</key>
+        <string>episode</string>
+        <key>equialent</key>
+        <string>equivalent</string>
+        <key>equilibium</key>
+        <string>equilibrium</string>
+        <key>equilibrum</key>
+        <string>equilibrium</string>
+        <key>equiped</key>
+        <string>equipped</string>
+        <key>equippment</key>
+        <string>equipment</string>
+        <key>equitorial</key>
+        <string>equatorial</string>
+        <key>equivelant</key>
+        <string>equivalent</string>
+        <key>equivelent</key>
+        <string>equivalent</string>
+        <key>equivilant</key>
+        <string>equivalent</string>
+        <key>equivilent</key>
+        <string>equivalent</string>
+        <key>equivlalent</key>
+        <string>equivalent</string>
+        <key>erally</key>
+        <string>really</string>
+        <key>eratic</key>
+        <string>erratic</string>
+        <key>eratically</key>
+        <string>erratically</string>
+        <key>eraticly</key>
+        <string>erratically</string>
+        <key>errupted</key>
+        <string>erupted</string>
+        <key>esential</key>
+        <string>essential</string>
+        <key>esitmated</key>
+        <string>estimated</string>
+        <key>esle</key>
+        <string>else</string>
+        <key>especialy</key>
+        <string>especially</string>
+        <key>essencial</key>
+        <string>essential</string>
+        <key>essense</key>
+        <string>essence</string>
+        <key>essentail</key>
+        <string>essential</string>
+        <key>essentialy</key>
+        <string>essentially</string>
+        <key>essentual</key>
+        <string>essential</string>
+        <key>essesital</key>
+        <string>essential</string>
+        <key>estabishes</key>
+        <string>establishes</string>
+        <key>establising</key>
+        <string>establishing</string>
+        <key>ethnocentricm</key>
+        <string>ethnocentrism</string>
+        <key>ethose</key>
+        <string>those</string>
+        <key>evenhtually</key>
+        <string>eventually</string>
+        <key>eventally</key>
+        <string>eventually</string>
+        <key>eventhough</key>
+        <string>even though</string>
+        <key>eventially</key>
+        <string>eventually</string>
+        <key>eventualy</key>
+        <string>eventually</string>
+        <key>everthing</key>
+        <string>everything</string>
+        <key>everytime</key>
+        <string>every time</string>
+        <key>everyting</key>
+        <string>everything</string>
+        <key>eveyr</key>
+        <string>every</string>
+        <key>evidentally</key>
+        <string>evidently</string>
+        <key>exagerate</key>
+        <string>exaggerate</string>
+        <key>exagerated</key>
+        <string>exaggerated</string>
+        <key>exagerates</key>
+        <string>exaggerates</string>
+        <key>exagerating</key>
+        <string>exaggerating</string>
+        <key>exagerrate</key>
+        <string>exaggerate</string>
+        <key>exagerrated</key>
+        <string>exaggerated</string>
+        <key>exagerrates</key>
+        <string>exaggerates</string>
+        <key>exagerrating</key>
+        <string>exaggerating</string>
+        <key>examinated</key>
+        <string>examined</string>
+        <key>exampt</key>
+        <string>exempt</string>
+        <key>exapansion</key>
+        <string>expansion</string>
+        <key>excact</key>
+        <string>exact</string>
+        <key>excange</key>
+        <string>exchange</string>
+        <key>excecute</key>
+        <string>execute</string>
+        <key>excecuted</key>
+        <string>executed</string>
+        <key>excecutes</key>
+        <string>executes</string>
+        <key>excecuting</key>
+        <string>executing</string>
+        <key>excecution</key>
+        <string>execution</string>
+        <key>excedded</key>
+        <string>exceeded</string>
+        <key>excelent</key>
+        <string>excellent</string>
+        <key>excell</key>
+        <string>excel</string>
+        <key>excellance</key>
+        <string>excellence</string>
+        <key>excellant</key>
+        <string>excellent</string>
+        <key>excells</key>
+        <string>excels</string>
+        <key>excercise</key>
+        <string>exercise</string>
+        <key>exchanching</key>
+        <string>exchanging</string>
+        <key>excisted</key>
+        <string>existed</string>
+        <key>exculsivly</key>
+        <string>exclusively</string>
+        <key>execising</key>
+        <string>exercising</string>
+        <key>exection</key>
+        <string>execution</string>
+        <key>exectued</key>
+        <string>executed</string>
+        <key>exeedingly</key>
+        <string>exceedingly</string>
+        <key>exelent</key>
+        <string>excellent</string>
+        <key>exellent</key>
+        <string>excellent</string>
+        <key>exemple</key>
+        <string>example</string>
+        <key>exept</key>
+        <string>except</string>
+        <key>exeptional</key>
+        <string>exceptional</string>
+        <key>exerbate</key>
+        <string>exacerbate</string>
+        <key>exerbated</key>
+        <string>exacerbated</string>
+        <key>exerciese</key>
+        <string>exercises</string>
+        <key>exerpt</key>
+        <string>excerpt</string>
+        <key>exerpts</key>
+        <string>excerpts</string>
+        <key>exersize</key>
+        <string>exercise</string>
+        <key>exerternal</key>
+        <string>external</string>
+        <key>exhalted</key>
+        <string>exalted</string>
+        <key>exhibtion</key>
+        <string>exhibition</string>
+        <key>exibition</key>
+        <string>exhibition</string>
+        <key>exibitions</key>
+        <string>exhibitions</string>
+        <key>exicting</key>
+        <string>exciting</string>
+        <key>exinct</key>
+        <string>extinct</string>
+        <key>existance</key>
+        <string>existence</string>
+        <key>existant</key>
+        <string>existent</string>
+        <key>existince</key>
+        <string>existence</string>
+        <key>exliled</key>
+        <string>exiled</string>
+        <key>exludes</key>
+        <string>excludes</string>
+        <key>exmaple</key>
+        <string>example</string>
+        <key>exonorate</key>
+        <string>exonerate</string>
+        <key>exoskelaton</key>
+        <string>exoskeleton</string>
+        <key>expalin</key>
+        <string>explain</string>
+        <key>expatriot</key>
+        <string>expatriate</string>
+        <key>expeced</key>
+        <string>expected</string>
+        <key>expecially</key>
+        <string>especially</string>
+        <key>expeditonary</key>
+        <string>expeditionary</string>
+        <key>expeiments</key>
+        <string>experiments</string>
+        <key>expell</key>
+        <string>expel</string>
+        <key>expells</key>
+        <string>expels</string>
+        <key>experiance</key>
+        <string>experience</string>
+        <key>experianced</key>
+        <string>experienced</string>
+        <key>expiditions</key>
+        <string>expeditions</string>
+        <key>expierence</key>
+        <string>experience</string>
+        <key>explaination</key>
+        <string>explanation</string>
+        <key>explaning</key>
+        <string>explaining</string>
+        <key>explictly</key>
+        <string>explicitly</string>
+        <key>exploititive</key>
+        <string>exploitative</string>
+        <key>explotation</key>
+        <string>exploitation</string>
+        <key>expropiated</key>
+        <string>expropriated</string>
+        <key>expropiation</key>
+        <string>expropriation</string>
+        <key>exressed</key>
+        <string>expressed</string>
+        <key>extemely</key>
+        <string>extremely</string>
+        <key>extention</key>
+        <string>extension</string>
+        <key>extentions</key>
+        <string>extensions</string>
+        <key>extered</key>
+        <string>exerted</string>
+        <key>extermist</key>
+        <string>extremist</string>
+        <key>extint</key>
+        <string>extinct</string>
+        <key>extradiction</key>
+        <string>extradition</string>
+        <key>extraterrestial</key>
+        <string>extraterrestrial</string>
+        <key>extraterrestials</key>
+        <string>extraterrestrials</string>
+        <key>extravagent</key>
+        <string>extravagant</string>
+        <key>extrememly</key>
+        <string>extremely</string>
+        <key>extremeophile</key>
+        <string>extremophile</string>
+        <key>extremly</key>
+        <string>extremely</string>
+        <key>extrordinarily</key>
+        <string>extraordinarily</string>
+        <key>extrordinary</key>
+        <string>extraordinary</string>
+        <key>eyar</key>
+        <string>year</string>
+        <key>eyars</key>
+        <string>years</string>
+        <key>eyasr</key>
+        <string>years</string>
+        <key>faciliate</key>
+        <string>facilitate</string>
+        <key>faciliated</key>
+        <string>facilitated</string>
+        <key>faciliates</key>
+        <string>facilitates</string>
+        <key>facilites</key>
+        <string>facilities</string>
+        <key>facillitate</key>
+        <string>facilitate</string>
+        <key>facinated</key>
+        <string>fascinated</string>
+        <key>facist</key>
+        <string>fascist</string>
+        <key>familes</key>
+        <string>families</string>
+        <key>familliar</key>
+        <string>familiar</string>
+        <key>famoust</key>
+        <string>famous</string>
+        <key>fanatism</key>
+        <string>fanaticism</string>
+        <key>fatc</key>
+        <string>fact</string>
+        <key>faught</key>
+        <string>fought</string>
+        <key>favoutrable</key>
+        <string>favourable</string>
+        <key>feasable</key>
+        <string>feasible</string>
+        <key>fedreally</key>
+        <string>federally</string>
+        <key>feromone</key>
+        <string>pheromone</string>
+        <key>fertily</key>
+        <string>fertility</string>
+        <key>fianite</key>
+        <string>finite</string>
+        <key>fianlly</key>
+        <string>finally</string>
+        <key>ficticious</key>
+        <string>fictitious</string>
+        <key>fictious</key>
+        <string>fictitious</string>
+        <key>fidn</key>
+        <string>find</string>
+        <key>fiercly</key>
+        <string>fiercely</string>
+        <key>fightings</key>
+        <string>fighting</string>
+        <key>filiament</key>
+        <string>filament</string>
+        <key>fimilies</key>
+        <string>families</string>
+        <key>finacial</key>
+        <string>financial</string>
+        <key>finaly</key>
+        <string>finally</string>
+        <key>financialy</key>
+        <string>financially</string>
+        <key>firends</key>
+        <string>friends</string>
+        <key>firts</key>
+        <string>first</string>
+        <key>fisionable</key>
+        <string>fissionable</string>
+        <key>flamable</key>
+        <string>flammable</string>
+        <key>flawess</key>
+        <string>flawless</string>
+        <key>fleed</key>
+        <string>fled</string>
+        <key>florescent</key>
+        <string>fluorescent</string>
+        <key>flourescent</key>
+        <string>fluorescent</string>
+        <key>flourine</key>
+        <string>fluorine</string>
+        <key>fluorish</key>
+        <string>flourish</string>
+        <key>follwoing</key>
+        <string>following</string>
+        <key>folowing</key>
+        <string>following</string>
+        <key>fomed</key>
+        <string>formed</string>
+        <key>fomr</key>
+        <string>from</string>
+        <key>fonetic</key>
+        <string>phonetic</string>
+        <key>fontrier</key>
+        <string>fontier</string>
+        <key>foootball</key>
+        <string>football</string>
+        <key>forbad</key>
+        <string>forbade</string>
+        <key>forbiden</key>
+        <string>forbidden</string>
+        <key>foreward</key>
+        <string>foreword</string>
+        <key>forfiet</key>
+        <string>forfeit</string>
+        <key>forhead</key>
+        <string>forehead</string>
+        <key>foriegn</key>
+        <string>foreign</string>
+        <key>formallize</key>
+        <string>formalize</string>
+        <key>formallized</key>
+        <string>formalized</string>
+        <key>formaly</key>
+        <string>formally</string>
+        <key>formelly</key>
+        <string>formerly</string>
+        <key>formidible</key>
+        <string>formidable</string>
+        <key>formost</key>
+        <string>foremost</string>
+        <key>forsaw</key>
+        <string>foresaw</string>
+        <key>forseeable</key>
+        <string>foreseeable</string>
+        <key>fortelling</key>
+        <string>foretelling</string>
+        <key>forunner</key>
+        <string>forerunner</string>
+        <key>foucs</key>
+        <string>focus</string>
+        <key>foudn</key>
+        <string>found</string>
+        <key>fougth</key>
+        <string>fought</string>
+        <key>foundaries</key>
+        <string>foundries</string>
+        <key>foundary</key>
+        <string>foundry</string>
+        <key>fourties</key>
+        <string>forties</string>
+        <key>fourty</key>
+        <string>forty</string>
+        <key>fouth</key>
+        <string>fourth</string>
+        <key>foward</key>
+        <string>forward</string>
+        <key>freind</key>
+        <string>friend</string>
+        <key>freindly</key>
+        <string>friendly</string>
+        <key>frequentily</key>
+        <string>frequently</string>
+        <key>frome</key>
+        <string>from</string>
+        <key>fromed</key>
+        <string>formed</string>
+        <key>froniter</key>
+        <string>frontier</string>
+        <key>fucntion</key>
+        <string>function</string>
+        <key>fucntioning</key>
+        <string>functioning</string>
+        <key>fufill</key>
+        <string>fulfill</string>
+        <key>fufilled</key>
+        <string>fulfilled</string>
+        <key>fulfiled</key>
+        <string>fulfilled</string>
+        <key>fullfill</key>
+        <string>fulfill</string>
+        <key>fullfilled</key>
+        <string>fulfilled</string>
+        <key>fundametal</key>
+        <string>fundamental</string>
+        <key>fundametals</key>
+        <string>fundamentals</string>
+        <key>funguses</key>
+        <string>fungi</string>
+        <key>funtion</key>
+        <string>function</string>
+        <key>furuther</key>
+        <string>further</string>
+        <key>futher</key>
+        <string>further</string>
+        <key>futhermore</key>
+        <string>furthermore</string>
+        <key>galatic</key>
+        <string>galactic</string>
+        <key>gallaxies</key>
+        <string>galaxies</string>
+        <key>galvinized</key>
+        <string>galvanized</string>
+        <key>ganerate</key>
+        <string>generate</string>
+        <key>ganes</key>
+        <string>games</string>
+        <key>ganster</key>
+        <string>gangster</string>
+        <key>garantee</key>
+        <string>guarantee</string>
+        <key>garanteed</key>
+        <string>guaranteed</string>
+        <key>garantees</key>
+        <string>guarantees</string>
+        <key>garnison</key>
+        <string>garrison</string>
+        <key>gaurantee</key>
+        <string>guarantee</string>
+        <key>gauranteed</key>
+        <string>guaranteed</string>
+        <key>gaurantees</key>
+        <string>guarantees</string>
+        <key>gaurd</key>
+        <string>guard</string>
+        <key>gaurentee</key>
+        <string>guarantee</string>
+        <key>gaurenteed</key>
+        <string>guaranteed</string>
+        <key>gaurentees</key>
+        <string>guarantees</string>
+        <key>geneological</key>
+        <string>genealogical</string>
+        <key>geneologies</key>
+        <string>genealogies</string>
+        <key>geneology</key>
+        <string>genealogy</string>
+        <key>generaly</key>
+        <string>generally</string>
+        <key>generatting</key>
+        <string>generating</string>
+        <key>genialia</key>
+        <string>genitalia</string>
+        <key>geographicial</key>
+        <string>geographical</string>
+        <key>geometrician</key>
+        <string>geometer</string>
+        <key>geometricians</key>
+        <string>geometers</string>
+        <key>gerat</key>
+        <string>great</string>
+        <key>glight</key>
+        <string>flight</string>
+        <key>gnawwed</key>
+        <string>gnawed</string>
+        <key>godess</key>
+        <string>goddess</string>
+        <key>godesses</key>
+        <string>goddesses</string>
+        <key>gogin</key>
+        <string>going</string>
+        <key>goign</key>
+        <string>going</string>
+        <key>gonig</key>
+        <string>going</string>
+        <key>gouvener</key>
+        <string>governor</string>
+        <key>govement</key>
+        <string>government</string>
+        <key>govenment</key>
+        <string>government</string>
+        <key>govenrment</key>
+        <string>government</string>
+        <key>goverance</key>
+        <string>governance</string>
+        <key>goverment</key>
+        <string>government</string>
+        <key>govermental</key>
+        <string>governmental</string>
+        <key>governer</key>
+        <string>governor</string>
+        <key>governmnet</key>
+        <string>government</string>
+        <key>govorment</key>
+        <string>government</string>
+        <key>govormental</key>
+        <string>governmental</string>
+        <key>govornment</key>
+        <string>government</string>
+        <key>gracefull</key>
+        <string>graceful</string>
+        <key>graet</key>
+        <string>great</string>
+        <key>grafitti</key>
+        <string>graffiti</string>
+        <key>gramatically</key>
+        <string>grammatically</string>
+        <key>grammaticaly</key>
+        <string>grammatically</string>
+        <key>grammer</key>
+        <string>grammar</string>
+        <key>grat</key>
+        <string>great</string>
+        <key>gratuitious</key>
+        <string>gratuitous</string>
+        <key>greatful</key>
+        <string>grateful</string>
+        <key>greatfully</key>
+        <string>gratefully</string>
+        <key>greif</key>
+        <string>grief</string>
+        <key>gridles</key>
+        <string>griddles</string>
+        <key>gropu</key>
+        <string>group</string>
+        <key>grwo</key>
+        <string>grow</string>
+        <key>guage</key>
+        <string>gauge</string>
+        <key>guarentee</key>
+        <string>guarantee</string>
+        <key>guarenteed</key>
+        <string>guaranteed</string>
+        <key>guarentees</key>
+        <string>guarantees</string>
+        <key>guerilla</key>
+        <string>guerrilla</string>
+        <key>guerillas</key>
+        <string>guerrillas</string>
+        <key>guerrila</key>
+        <string>guerrilla</string>
+        <key>guerrilas</key>
+        <string>guerrillas</string>
+        <key>guidence</key>
+        <string>guidance</string>
+        <key>gunanine</key>
+        <string>guanine</string>
+        <key>gurantee</key>
+        <string>guarantee</string>
+        <key>guranteed</key>
+        <string>guaranteed</string>
+        <key>gurantees</key>
+        <string>guarantees</string>
+        <key>guttaral</key>
+        <string>guttural</string>
+        <key>gutteral</key>
+        <string>guttural</string>
+        <key>habaeus</key>
+        <string>habeas</string>
+        <key>habeus</key>
+        <string>habeas</string>
+        <key>haemorrage</key>
+        <string>haemorrhage</string>
+        <key>haev</key>
+        <string>have</string>
+        <key>halp</key>
+        <string>help</string>
+        <key>hapen</key>
+        <string>happen</string>
+        <key>hapened</key>
+        <string>happened</string>
+        <key>hapening</key>
+        <string>happening</string>
+        <key>happend</key>
+        <string>happened</string>
+        <key>happended</key>
+        <string>happened</string>
+        <key>happenned</key>
+        <string>happened</string>
+        <key>harased</key>
+        <string>harassed</string>
+        <key>harases</key>
+        <string>harasses</string>
+        <key>harasment</key>
+        <string>harassment</string>
+        <key>harasments</key>
+        <string>harassments</string>
+        <key>harassement</key>
+        <string>harassment</string>
+        <key>harras</key>
+        <string>harass</string>
+        <key>harrased</key>
+        <string>harassed</string>
+        <key>harrases</key>
+        <string>harasses</string>
+        <key>harrasing</key>
+        <string>harassing</string>
+        <key>harrasment</key>
+        <string>harassment</string>
+        <key>harrasments</key>
+        <string>harassments</string>
+        <key>harrassed</key>
+        <string>harassed</string>
+        <key>harrasses</key>
+        <string>harassed</string>
+        <key>harrassing</key>
+        <string>harassing</string>
+        <key>harrassment</key>
+        <string>harassment</string>
+        <key>harrassments</key>
+        <string>harassments</string>
+        <key>hasnt</key>
+        <string>hasn&apos;t</string>
+        <key>haviest</key>
+        <string>heaviest</string>
+        <key>headquarer</key>
+        <string>headquarter</string>
+        <key>headquater</key>
+        <string>headquarter</string>
+        <key>headquatered</key>
+        <string>headquartered</string>
+        <key>headquaters</key>
+        <string>headquarters</string>
+        <key>healthercare</key>
+        <string>healthcare</string>
+        <key>heared</key>
+        <string>heard</string>
+        <key>heathy</key>
+        <string>healthy</string>
+        <key>heigher</key>
+        <string>higher</string>
+        <key>heirarchy</key>
+        <string>hierarchy</string>
+        <key>heiroglyphics</key>
+        <string>hieroglyphics</string>
+        <key>helment</key>
+        <string>helmet</string>
+        <key>helpfull</key>
+        <string>helpful</string>
+        <key>helpped</key>
+        <string>helped</string>
+        <key>hemmorhage</key>
+        <string>hemorrhage</string>
+        <key>herad</key>
+        <string>heard</string>
+        <key>heridity</key>
+        <string>heredity</string>
+        <key>heroe</key>
+        <string>hero</string>
+        <key>heros</key>
+        <string>heroes</string>
+        <key>hertiage</key>
+        <string>heritage</string>
+        <key>hertzs</key>
+        <string>hertz</string>
+        <key>hesistant</key>
+        <string>hesitant</string>
+        <key>heterogenous</key>
+        <string>heterogeneous</string>
+        <key>hieght</key>
+        <string>height</string>
+        <key>hierachical</key>
+        <string>hierarchical</string>
+        <key>hierachies</key>
+        <string>hierarchies</string>
+        <key>hierachy</key>
+        <string>hierarchy</string>
+        <key>hierarcical</key>
+        <string>hierarchical</string>
+        <key>hierarcy</key>
+        <string>hierarchy</string>
+        <key>hieroglph</key>
+        <string>hieroglyph</string>
+        <key>hieroglphs</key>
+        <string>hieroglyphs</string>
+        <key>higer</key>
+        <string>higher</string>
+        <key>higest</key>
+        <string>highest</string>
+        <key>higway</key>
+        <string>highway</string>
+        <key>hillarious</key>
+        <string>hilarious</string>
+        <key>himselv</key>
+        <string>himself</string>
+        <key>hinderance</key>
+        <string>hindrance</string>
+        <key>hinderence</key>
+        <string>hindrance</string>
+        <key>hindrence</key>
+        <string>hindrance</string>
+        <key>hipopotamus</key>
+        <string>hippopotamus</string>
+        <key>hismelf</key>
+        <string>himself</string>
+        <key>histocompatability</key>
+        <string>histocompatibility</string>
+        <key>historicians</key>
+        <string>historians</string>
+        <key>hitsingles</key>
+        <string>hit singles</string>
+        <key>holliday</key>
+        <string>holiday</string>
+        <key>homestate</key>
+        <string>home state</string>
+        <key>homogeneize</key>
+        <string>homogenize</string>
+        <key>homogeneized</key>
+        <string>homogenized</string>
+        <key>honory</key>
+        <string>honorary</string>
+        <key>horrifing</key>
+        <string>horrifying</string>
+        <key>hosited</key>
+        <string>hoisted</string>
+        <key>hospitible</key>
+        <string>hospitable</string>
+        <key>hounour</key>
+        <string>honour</string>
+        <key>housr</key>
+        <string>hours</string>
+        <key>howver</key>
+        <string>however</string>
+        <key>hsitorians</key>
+        <string>historians</string>
+        <key>hstory</key>
+        <string>history</string>
+        <key>hten</key>
+        <string>then</string>
+        <key>htere</key>
+        <string>there</string>
+        <key>htey</key>
+        <string>they</string>
+        <key>htikn</key>
+        <string>think</string>
+        <key>hting</key>
+        <string>thing</string>
+        <key>htink</key>
+        <string>think</string>
+        <key>htis</key>
+        <string>this</string>
+        <key>humer</key>
+        <string>humor</string>
+        <key>humerous</key>
+        <string>humorous</string>
+        <key>huminoid</key>
+        <string>humanoid</string>
+        <key>humoural</key>
+        <string>humoral</string>
+        <key>humurous</key>
+        <string>humorous</string>
+        <key>husban</key>
+        <string>husband</string>
+        <key>hvae</key>
+        <string>have</string>
+        <key>hvaing</key>
+        <string>having</string>
+        <key>hvea</key>
+        <string>have</string>
+        <key>hwihc</key>
+        <string>which</string>
+        <key>hwile</key>
+        <string>while</string>
+        <key>hwole</key>
+        <string>whole</string>
+        <key>hydogen</key>
+        <string>hydrogen</string>
+        <key>hydropile</key>
+        <string>hydrophile</string>
+        <key>hydropilic</key>
+        <string>hydrophilic</string>
+        <key>hydropobe</key>
+        <string>hydrophobe</string>
+        <key>hydropobic</key>
+        <string>hydrophobic</string>
+        <key>hygeine</key>
+        <string>hygiene</string>
+        <key>hypocracy</key>
+        <string>hypocrisy</string>
+        <key>hypocrasy</key>
+        <string>hypocrisy</string>
+        <key>hypocricy</key>
+        <string>hypocrisy</string>
+        <key>hypocrit</key>
+        <string>hypocrite</string>
+        <key>hypocrits</key>
+        <string>hypocrites</string>
+        <key>i</key>
+        <string>I</string>
+        <key>iconclastic</key>
+        <string>iconoclastic</string>
+        <key>idaeidae</key>
+        <string>idea</string>
+        <key>idaes</key>
+        <string>ideas</string>
+        <key>idealogies</key>
+        <string>ideologies</string>
+        <key>idealogy</key>
+        <string>ideology</string>
+        <key>identicial</key>
+        <string>identical</string>
+        <key>identifers</key>
+        <string>identifiers</string>
+        <key>ideosyncratic</key>
+        <string>idiosyncratic</string>
+        <key>idesa</key>
+        <string>ideas</string>
+        <key>idiosyncracy</key>
+        <string>idiosyncrasy</string>
+        <key>illegimacy</key>
+        <string>illegitimacy</string>
+        <key>illegitmate</key>
+        <string>illegitimate</string>
+        <key>illess</key>
+        <string>illness</string>
+        <key>illiegal</key>
+        <string>illegal</string>
+        <key>illution</key>
+        <string>illusion</string>
+        <key>ilness</key>
+        <string>illness</string>
+        <key>ilogical</key>
+        <string>illogical</string>
+        <key>imagenary</key>
+        <string>imaginary</string>
+        <key>imagin</key>
+        <string>imagine</string>
+        <key>imaginery</key>
+        <string>imaginary</string>
+        <key>imcomplete</key>
+        <string>incomplete</string>
+        <key>imediately</key>
+        <string>immediately</string>
+        <key>imense</key>
+        <string>immense</string>
+        <key>immediatley</key>
+        <string>immediately</string>
+        <key>immediatly</key>
+        <string>immediately</string>
+        <key>immidately</key>
+        <string>immediately</string>
+        <key>immidiately</key>
+        <string>immediately</string>
+        <key>immitate</key>
+        <string>imitate</string>
+        <key>immitated</key>
+        <string>imitated</string>
+        <key>immitating</key>
+        <string>imitating</string>
+        <key>immitator</key>
+        <string>imitator</string>
+        <key>immunosupressant</key>
+        <string>immunosuppressant</string>
+        <key>impecabbly</key>
+        <string>impeccably</string>
+        <key>impedence</key>
+        <string>impedance</string>
+        <key>implamenting</key>
+        <string>implementing</string>
+        <key>impliment</key>
+        <string>implement</string>
+        <key>implimented</key>
+        <string>implemented</string>
+        <key>imploys</key>
+        <string>employs</string>
+        <key>importamt</key>
+        <string>important</string>
+        <key>imprioned</key>
+        <string>imprisoned</string>
+        <key>imprisonned</key>
+        <string>imprisoned</string>
+        <key>improvision</key>
+        <string>improvisation</string>
+        <key>improvments</key>
+        <string>improvements</string>
+        <key>inablility</key>
+        <string>inability</string>
+        <key>inaccessable</key>
+        <string>inaccessible</string>
+        <key>inadiquate</key>
+        <string>inadequate</string>
+        <key>inadquate</key>
+        <string>inadequate</string>
+        <key>inadvertant</key>
+        <string>inadvertent</string>
+        <key>inadvertantly</key>
+        <string>inadvertently</string>
+        <key>inagurated</key>
+        <string>inaugurated</string>
+        <key>inaguration</key>
+        <string>inauguration</string>
+        <key>inappropiate</key>
+        <string>inappropriate</string>
+        <key>inaugures</key>
+        <string>inaugurates</string>
+        <key>inbalance</key>
+        <string>imbalance</string>
+        <key>inbalanced</key>
+        <string>imbalanced</string>
+        <key>inbetween</key>
+        <string>between</string>
+        <key>incarcirated</key>
+        <string>incarcerated</string>
+        <key>incidentially</key>
+        <string>incidentally</string>
+        <key>incidently</key>
+        <string>incidentally</string>
+        <key>inclreased</key>
+        <string>increased</string>
+        <key>includ</key>
+        <string>include</string>
+        <key>includng</key>
+        <string>including</string>
+        <key>incompatabilities</key>
+        <string>incompatibilities</string>
+        <key>incompatability</key>
+        <string>incompatibility</string>
+        <key>incompatable</key>
+        <string>incompatible</string>
+        <key>incompatablities</key>
+        <string>incompatibilities</string>
+        <key>incompatablity</key>
+        <string>incompatibility</string>
+        <key>incompatiblities</key>
+        <string>incompatibilities</string>
+        <key>incompatiblity</key>
+        <string>incompatibility</string>
+        <key>incompetance</key>
+        <string>incompetence</string>
+        <key>incompetant</key>
+        <string>incompetent</string>
+        <key>incomptable</key>
+        <string>incompatible</string>
+        <key>incomptetent</key>
+        <string>incompetent</string>
+        <key>inconsistant</key>
+        <string>inconsistent</string>
+        <key>incoroporated</key>
+        <string>incorporated</string>
+        <key>incorperation</key>
+        <string>incorporation</string>
+        <key>incorportaed</key>
+        <string>incorporated</string>
+        <key>incorprates</key>
+        <string>incorporates</string>
+        <key>incorruptable</key>
+        <string>incorruptible</string>
+        <key>incramentally</key>
+        <string>incrementally</string>
+        <key>increadible</key>
+        <string>incredible</string>
+        <key>incredable</key>
+        <string>incredible</string>
+        <key>inctroduce</key>
+        <string>introduce</string>
+        <key>inctroduced</key>
+        <string>introduced</string>
+        <key>incuding</key>
+        <string>including</string>
+        <key>incunabla</key>
+        <string>incunabula</string>
+        <key>indefinately</key>
+        <string>indefinitely</string>
+        <key>indefineable</key>
+        <string>undefinable</string>
+        <key>indefinitly</key>
+        <string>indefinitely</string>
+        <key>indentical</key>
+        <string>identical</string>
+        <key>indepedantly</key>
+        <string>independently</string>
+        <key>indepedence</key>
+        <string>independence</string>
+        <key>independance</key>
+        <string>independence</string>
+        <key>independant</key>
+        <string>independent</string>
+        <key>independantly</key>
+        <string>independently</string>
+        <key>independece</key>
+        <string>independence</string>
+        <key>independendet</key>
+        <string>independent</string>
+        <key>indespensable</key>
+        <string>indispensable</string>
+        <key>indespensible</key>
+        <string>indispensable</string>
+        <key>indictement</key>
+        <string>indictment</string>
+        <key>indigineous</key>
+        <string>indigenous</string>
+        <key>indipendence</key>
+        <string>independence</string>
+        <key>indipendent</key>
+        <string>independent</string>
+        <key>indipendently</key>
+        <string>independently</string>
+        <key>indispensible</key>
+        <string>indispensable</string>
+        <key>indisputible</key>
+        <string>indisputable</string>
+        <key>indisputibly</key>
+        <string>indisputably</string>
+        <key>indite</key>
+        <string>indict</string>
+        <key>individualy</key>
+        <string>individually</string>
+        <key>indpendent</key>
+        <string>independent</string>
+        <key>indpendently</key>
+        <string>independently</string>
+        <key>indulgue</key>
+        <string>indulge</string>
+        <key>indutrial</key>
+        <string>industrial</string>
+        <key>indviduals</key>
+        <string>individuals</string>
+        <key>inefficienty</key>
+        <string>inefficiently</string>
+        <key>inevatible</key>
+        <string>inevitable</string>
+        <key>inevitible</key>
+        <string>inevitable</string>
+        <key>inevititably</key>
+        <string>inevitably</string>
+        <key>infalability</key>
+        <string>infallibility</string>
+        <key>infallable</key>
+        <string>infallible</string>
+        <key>infectuous</key>
+        <string>infectious</string>
+        <key>infered</key>
+        <string>inferred</string>
+        <key>infilitrate</key>
+        <string>infiltrate</string>
+        <key>infilitrated</key>
+        <string>infiltrated</string>
+        <key>infilitration</key>
+        <string>infiltration</string>
+        <key>infinit</key>
+        <string>infinite</string>
+        <key>inflamation</key>
+        <string>inflammation</string>
+        <key>influencial</key>
+        <string>influential</string>
+        <key>influented</key>
+        <string>influenced</string>
+        <key>infomation</key>
+        <string>information</string>
+        <key>informtion</key>
+        <string>information</string>
+        <key>infrantryman</key>
+        <string>infantryman</string>
+        <key>infrigement</key>
+        <string>infringement</string>
+        <key>ingenius</key>
+        <string>ingenious</string>
+        <key>ingreediants</key>
+        <string>ingredients</string>
+        <key>inhabitans</key>
+        <string>inhabitants</string>
+        <key>inherantly</key>
+        <string>inherently</string>
+        <key>inheritence</key>
+        <string>inheritance</string>
+        <key>inital</key>
+        <string>initial</string>
+        <key>initally</key>
+        <string>initially</string>
+        <key>initation</key>
+        <string>initiation</string>
+        <key>initiaitive</key>
+        <string>initiative</string>
+        <key>inlcuding</key>
+        <string>including</string>
+        <key>inmigrant</key>
+        <string>immigrant</string>
+        <key>inmigrants</key>
+        <string>immigrants</string>
+        <key>innoculated</key>
+        <string>inoculated</string>
+        <key>inocence</key>
+        <string>innocence</string>
+        <key>inofficial</key>
+        <string>unofficial</string>
+        <key>inot</key>
+        <string>into</string>
+        <key>inpeach</key>
+        <string>impeach</string>
+        <key>inpolite</key>
+        <string>impolite</string>
+        <key>inprisonment</key>
+        <string>imprisonment</string>
+        <key>inproving</key>
+        <string>improving</string>
+        <key>insectiverous</key>
+        <string>insectivorous</string>
+        <key>insensative</key>
+        <string>insensitive</string>
+        <key>inseperable</key>
+        <string>inseparable</string>
+        <key>insistance</key>
+        <string>insistence</string>
+        <key>insitution</key>
+        <string>institution</string>
+        <key>insitutions</key>
+        <string>institutions</string>
+        <key>inspite</key>
+        <string>in spite</string>
+        <key>instade</key>
+        <string>instead</string>
+        <key>instatance</key>
+        <string>instance</string>
+        <key>institue</key>
+        <string>institute</string>
+        <key>instuction</key>
+        <string>instruction</string>
+        <key>instuments</key>
+        <string>instruments</string>
+        <key>instutionalized</key>
+        <string>institutionalized</string>
+        <key>instutions</key>
+        <string>intuitions</string>
+        <key>insurence</key>
+        <string>insurance</string>
+        <key>intelectual</key>
+        <string>intellectual</string>
+        <key>inteligence</key>
+        <string>intelligence</string>
+        <key>inteligent</key>
+        <string>intelligent</string>
+        <key>intenational</key>
+        <string>international</string>
+        <key>intented</key>
+        <string>intended</string>
+        <key>intepretation</key>
+        <string>interpretation</string>
+        <key>intepretator</key>
+        <string>interpretor</string>
+        <key>interational</key>
+        <string>international</string>
+        <key>interbread</key>
+        <string>interbreed</string>
+        <key>interchangable</key>
+        <string>interchangeable</string>
+        <key>interchangably</key>
+        <string>interchangeably</string>
+        <key>intercontinetal</key>
+        <string>intercontinental</string>
+        <key>intered</key>
+        <string>interred</string>
+        <key>interelated</key>
+        <string>interrelated</string>
+        <key>interferance</key>
+        <string>interference</string>
+        <key>interfereing</key>
+        <string>interfering</string>
+        <key>intergrated</key>
+        <string>integrated</string>
+        <key>intergration</key>
+        <string>integration</string>
+        <key>interm</key>
+        <string>interim</string>
+        <key>internation</key>
+        <string>international</string>
+        <key>interpet</key>
+        <string>interpret</string>
+        <key>interrim</key>
+        <string>interim</string>
+        <key>interrugum</key>
+        <string>interregnum</string>
+        <key>intertaining</key>
+        <string>entertaining</string>
+        <key>interupt</key>
+        <string>interrupt</string>
+        <key>intervines</key>
+        <string>intervenes</string>
+        <key>intevene</key>
+        <string>intervene</string>
+        <key>intial</key>
+        <string>initial</string>
+        <key>intially</key>
+        <string>initially</string>
+        <key>intrduced</key>
+        <string>introduced</string>
+        <key>intrest</key>
+        <string>interest</string>
+        <key>introdued</key>
+        <string>introduced</string>
+        <key>intruduced</key>
+        <string>introduced</string>
+        <key>intrument</key>
+        <string>instrument</string>
+        <key>intrumental</key>
+        <string>instrumental</string>
+        <key>intruments</key>
+        <string>instruments</string>
+        <key>intrusted</key>
+        <string>entrusted</string>
+        <key>intutive</key>
+        <string>intuitive</string>
+        <key>intutively</key>
+        <string>intuitively</string>
+        <key>inudstry</key>
+        <string>industry</string>
+        <key>inventer</key>
+        <string>inventor</string>
+        <key>invertibrates</key>
+        <string>invertebrates</string>
+        <key>investingate</key>
+        <string>investigate</string>
+        <key>involvment</key>
+        <string>involvement</string>
+        <key>irelevent</key>
+        <string>irrelevant</string>
+        <key>iresistable</key>
+        <string>irresistible</string>
+        <key>iresistably</key>
+        <string>irresistibly</string>
+        <key>iresistible</key>
+        <string>irresistible</string>
+        <key>iresistibly</key>
+        <string>irresistibly</string>
+        <key>iritable</key>
+        <string>irritable</string>
+        <key>iritated</key>
+        <string>irritated</string>
+        <key>ironicly</key>
+        <string>ironically</string>
+        <key>irregardless</key>
+        <string>regardless</string>
+        <key>irrelevent</key>
+        <string>irrelevant</string>
+        <key>irreplacable</key>
+        <string>irreplaceable</string>
+        <key>irresistable</key>
+        <string>irresistible</string>
+        <key>irresistably</key>
+        <string>irresistibly</string>
+        <key>isnt</key>
+        <string>isn&apos;t</string>
+        <key>issueing</key>
+        <string>issuing</string>
+        <key>itnroduced</key>
+        <string>introduced</string>
+        <key>iunior</key>
+        <string>junior</string>
+        <key>iwll</key>
+        <string>will</string>
+        <key>iwth</key>
+        <string>with</string>
+        <key>jaques</key>
+        <string>jacques</string>
+        <key>jeapardy</key>
+        <string>jeopardy</string>
+        <key>jewllery</key>
+        <string>jewellery</string>
+        <key>jouney</key>
+        <string>journey</string>
+        <key>journied</key>
+        <string>journeyed</string>
+        <key>journies</key>
+        <string>journeys</string>
+        <key>jstu</key>
+        <string>just</string>
+        <key>jsut</key>
+        <string>just</string>
+        <key>judical</key>
+        <string>judicial</string>
+        <key>judisuary</key>
+        <string>judiciary</string>
+        <key>juducial</key>
+        <string>judicial</string>
+        <key>juristiction</key>
+        <string>jurisdiction</string>
+        <key>juristictions</key>
+        <string>jurisdictions</string>
+        <key>kindergarden</key>
+        <string>kindergarten</string>
+        <key>klenex</key>
+        <string>kleenex</string>
+        <key>knifes</key>
+        <string>knives</string>
+        <key>knive</key>
+        <string>knife</string>
+        <key>knowlege</key>
+        <string>knowledge</string>
+        <key>knowlegeable</key>
+        <string>knowledgeable</string>
+        <key>knwo</key>
+        <string>know</string>
+        <key>knwos</key>
+        <string>knows</string>
+        <key>konw</key>
+        <string>know</string>
+        <key>konws</key>
+        <string>knows</string>
+        <key>kwno</key>
+        <string>know</string>
+        <key>labatory</key>
+        <string>laboratory</string>
+        <key>labratory</key>
+        <string>laboratory</string>
+        <key>laguage</key>
+        <string>language</string>
+        <key>laguages</key>
+        <string>languages</string>
+        <key>larg</key>
+        <string>large</string>
+        <key>largst</key>
+        <string>largest</string>
+        <key>larrry</key>
+        <string>larry</string>
+        <key>lastr</key>
+        <string>last</string>
+        <key>lattitude</key>
+        <string>latitude</string>
+        <key>launhed</key>
+        <string>launched</string>
+        <key>lavae</key>
+        <string>larvae</string>
+        <key>layed</key>
+        <string>laid</string>
+        <key>lazyness</key>
+        <string>laziness</string>
+        <key>leage</key>
+        <string>league</string>
+        <key>leanr</key>
+        <string>learn</string>
+        <key>leathal</key>
+        <string>lethal</string>
+        <key>lefted</key>
+        <string>left</string>
+        <key>legitamate</key>
+        <string>legitimate</string>
+        <key>legitmate</key>
+        <string>legitimate</string>
+        <key>leibnitz</key>
+        <string>leibniz</string>
+        <key>lenght</key>
+        <string>length</string>
+        <key>leran</key>
+        <string>learn</string>
+        <key>lerans</key>
+        <string>learns</string>
+        <key>leutenant</key>
+        <string>lieutenant</string>
+        <key>levetate</key>
+        <string>levitate</string>
+        <key>levetated</key>
+        <string>levitated</string>
+        <key>levetates</key>
+        <string>levitates</string>
+        <key>levetating</key>
+        <string>levitating</string>
+        <key>levle</key>
+        <string>level</string>
+        <key>liasion</key>
+        <string>liaison</string>
+        <key>liason</key>
+        <string>liaison</string>
+        <key>liasons</key>
+        <string>liaisons</string>
+        <key>libary</key>
+        <string>library</string>
+        <key>libell</key>
+        <string>libel</string>
+        <key>libguistic</key>
+        <string>linguistic</string>
+        <key>libguistics</key>
+        <string>linguistics</string>
+        <key>libitarianisn</key>
+        <string>libertarianism</string>
+        <key>lieing</key>
+        <string>lying</string>
+        <key>liek</key>
+        <string>like</string>
+        <key>liekd</key>
+        <string>liked</string>
+        <key>liesure</key>
+        <string>leisure</string>
+        <key>lieuenant</key>
+        <string>lieutenant</string>
+        <key>lieved</key>
+        <string>lived</string>
+        <key>liftime</key>
+        <string>lifetime</string>
+        <key>lightyear</key>
+        <string>light year</string>
+        <key>lightyears</key>
+        <string>light years</string>
+        <key>likelyhood</key>
+        <string>likelihood</string>
+        <key>linnaena</key>
+        <string>linnaean</string>
+        <key>lippizaner</key>
+        <string>lipizzaner</string>
+        <key>liquify</key>
+        <string>liquefy</string>
+        <key>liscense</key>
+        <string>license</string>
+        <key>lisence</key>
+        <string>license</string>
+        <key>lisense</key>
+        <string>license</string>
+        <key>listners</key>
+        <string>listeners</string>
+        <key>litature</key>
+        <string>literature</string>
+        <key>literaly</key>
+        <string>literally</string>
+        <key>literture</key>
+        <string>literature</string>
+        <key>littel</key>
+        <string>little</string>
+        <key>litterally</key>
+        <string>literally</string>
+        <key>liuke</key>
+        <string>like</string>
+        <key>livley</key>
+        <string>lively</string>
+        <key>lmits</key>
+        <string>limits</string>
+        <key>loev</key>
+        <string>love</string>
+        <key>lonelyness</key>
+        <string>loneliness</string>
+        <key>longitudonal</key>
+        <string>longitudinal</string>
+        <key>lonley</key>
+        <string>lonely</string>
+        <key>lonly</key>
+        <string>lonely</string>
+        <key>loosing</key>
+        <string>losing</string>
+        <key>lotharingen</key>
+        <string>lothringen</string>
+        <key>lsat</key>
+        <string>last</string>
+        <key>lukid</key>
+        <string>likud</string>
+        <key>lveo</key>
+        <string>love</string>
+        <key>lvoe</key>
+        <string>love</string>
+        <key>maching</key>
+        <string>machine</string>
+        <key>mackeral</key>
+        <string>mackerel</string>
+        <key>magasine</key>
+        <string>magazine</string>
+        <key>magincian</key>
+        <string>magician</string>
+        <key>magnificient</key>
+        <string>magnificent</string>
+        <key>magolia</key>
+        <string>magnolia</string>
+        <key>mailny</key>
+        <string>mainly</string>
+        <key>maintainance</key>
+        <string>maintenance</string>
+        <key>maintainence</key>
+        <string>maintenance</string>
+        <key>maintance</key>
+        <string>maintenance</string>
+        <key>maintenence</key>
+        <string>maintenance</string>
+        <key>maintinaing</key>
+        <string>maintaining</string>
+        <key>maintioned</key>
+        <string>mentioned</string>
+        <key>majoroty</key>
+        <string>majority</string>
+        <key>maked</key>
+        <string>marked</string>
+        <key>makse</key>
+        <string>makes</string>
+        <key>maltesian</key>
+        <string>Maltese</string>
+        <key>mamal</key>
+        <string>mammal</string>
+        <key>mamalian</key>
+        <string>mammalian</string>
+        <key>managable</key>
+        <string>manageable</string>
+        <key>managment</key>
+        <string>management</string>
+        <key>maneouvre</key>
+        <string>manoeuvre</string>
+        <key>maneouvred</key>
+        <string>manoeuvred</string>
+        <key>maneouvres</key>
+        <string>manoeuvres</string>
+        <key>maneouvring</key>
+        <string>manoeuvring</string>
+        <key>manisfestations</key>
+        <string>manifestations</string>
+        <key>manoeuverability</key>
+        <string>maneuverability</string>
+        <key>manouver</key>
+        <string>maneuver</string>
+        <key>manouverability</key>
+        <string>maneuverability</string>
+        <key>manouverable</key>
+        <string>maneuverable</string>
+        <key>manouvers</key>
+        <string>maneuvers</string>
+        <key>mantained</key>
+        <string>maintained</string>
+        <key>manuever</key>
+        <string>maneuver</string>
+        <key>manuevers</key>
+        <string>maneuvers</string>
+        <key>manufacturedd</key>
+        <string>manufactured</string>
+        <key>manufature</key>
+        <string>manufacture</string>
+        <key>manufatured</key>
+        <string>manufactured</string>
+        <key>manufaturing</key>
+        <string>manufacturing</string>
+        <key>manuver</key>
+        <string>maneuver</string>
+        <key>mariage</key>
+        <string>marriage</string>
+        <key>marjority</key>
+        <string>majority</string>
+        <key>markes</key>
+        <string>marks</string>
+        <key>marketting</key>
+        <string>marketing</string>
+        <key>marmelade</key>
+        <string>marmalade</string>
+        <key>marrage</key>
+        <string>marriage</string>
+        <key>marraige</key>
+        <string>marriage</string>
+        <key>marrtyred</key>
+        <string>martyred</string>
+        <key>marryied</key>
+        <string>married</string>
+        <key>massmedia</key>
+        <string>mass media</string>
+        <key>masterbation</key>
+        <string>masturbation</string>
+        <key>mataphysical</key>
+        <string>metaphysical</string>
+        <key>materalists</key>
+        <string>materialist</string>
+        <key>mathamatics</key>
+        <string>mathematics</string>
+        <key>mathematican</key>
+        <string>mathematician</string>
+        <key>mathematicas</key>
+        <string>mathematics</string>
+        <key>matheticians</key>
+        <string>mathematicians</string>
+        <key>mathmatically</key>
+        <string>mathematically</string>
+        <key>mathmatician</key>
+        <string>mathematician</string>
+        <key>mathmaticians</key>
+        <string>mathematicians</string>
+        <key>mccarthyst</key>
+        <string>mccarthyist</string>
+        <key>mchanics</key>
+        <string>mechanics</string>
+        <key>meaninng</key>
+        <string>meaning</string>
+        <key>mear</key>
+        <string>wear</string>
+        <key>mechandise</key>
+        <string>merchandise</string>
+        <key>medacine</key>
+        <string>medicine</string>
+        <key>medeival</key>
+        <string>medieval</string>
+        <key>medevial</key>
+        <string>medieval</string>
+        <key>mediciney</key>
+        <string>mediciny</string>
+        <key>medievel</key>
+        <string>medieval</string>
+        <key>mediterainnean</key>
+        <string>mediterranean</string>
+        <key>meerkrat</key>
+        <string>meerkat</string>
+        <key>melieux</key>
+        <string>milieux</string>
+        <key>membranaphone</key>
+        <string>membranophone</string>
+        <key>memeber</key>
+        <string>member</string>
+        <key>menally</key>
+        <string>mentally</string>
+        <key>meranda</key>
+        <string>Miranda</string>
+        <key>mercentile</key>
+        <string>mercantile</string>
+        <key>messanger</key>
+        <string>messenger</string>
+        <key>messenging</key>
+        <string>messaging</string>
+        <key>metalic</key>
+        <string>metallic</string>
+        <key>metalurgic</key>
+        <string>metallurgic</string>
+        <key>metalurgical</key>
+        <string>metallurgical</string>
+        <key>metalurgy</key>
+        <string>metallurgy</string>
+        <key>metamorphysis</key>
+        <string>metamorphosis</string>
+        <key>metaphoricial</key>
+        <string>metaphorical</string>
+        <key>meterologist</key>
+        <string>meteorologist</string>
+        <key>meterology</key>
+        <string>meteorology</string>
+        <key>methaphor</key>
+        <string>metaphor</string>
+        <key>methaphors</key>
+        <string>metaphors</string>
+        <key>micoscopy</key>
+        <string>microscopy</string>
+        <key>midwifes</key>
+        <string>midwives</string>
+        <key>mileau</key>
+        <string>milieu</string>
+        <key>milennia</key>
+        <string>millennia</string>
+        <key>milennium</key>
+        <string>millennium</string>
+        <key>mileu</key>
+        <string>milieu</string>
+        <key>miliary</key>
+        <string>military</string>
+        <key>milion</key>
+        <string>million</string>
+        <key>miliraty</key>
+        <string>military</string>
+        <key>millenia</key>
+        <string>millennia</string>
+        <key>millenial</key>
+        <string>millennial</string>
+        <key>millenialism</key>
+        <string>millennialism</string>
+        <key>millenium</key>
+        <string>millennium</string>
+        <key>millepede</key>
+        <string>millipede</string>
+        <key>millioniare</key>
+        <string>millionaire</string>
+        <key>millitary</key>
+        <string>military</string>
+        <key>millon</key>
+        <string>million</string>
+        <key>miltary</key>
+        <string>military</string>
+        <key>minature</key>
+        <string>miniature</string>
+        <key>minerial</key>
+        <string>mineral</string>
+        <key>miniscule</key>
+        <string>minuscule</string>
+        <key>ministery</key>
+        <string>ministry</string>
+        <key>minstries</key>
+        <string>ministries</string>
+        <key>minstry</key>
+        <string>ministry</string>
+        <key>minumum</key>
+        <string>minimum</string>
+        <key>mirrorred</key>
+        <string>mirrored</string>
+        <key>miscelaneous</key>
+        <string>miscellaneous</string>
+        <key>miscellanious</key>
+        <string>miscellaneous</string>
+        <key>miscellanous</key>
+        <string>miscellaneous</string>
+        <key>mischeivous</key>
+        <string>mischievous</string>
+        <key>mischevious</key>
+        <string>mischievous</string>
+        <key>mischievious</key>
+        <string>mischievous</string>
+        <key>misdameanor</key>
+        <string>misdemeanor</string>
+        <key>misdameanors</key>
+        <string>misdemeanors</string>
+        <key>misdemenor</key>
+        <string>misdemeanor</string>
+        <key>misdemenors</key>
+        <string>misdemeanors</string>
+        <key>misfourtunes</key>
+        <string>misfortunes</string>
+        <key>misile</key>
+        <string>missile</string>
+        <key>mispell</key>
+        <string>misspell</string>
+        <key>mispelled</key>
+        <string>misspelled</string>
+        <key>mispelling</key>
+        <string>misspelling</string>
+        <key>missen</key>
+        <string>mizzen</string>
+        <key>missle</key>
+        <string>missile</string>
+        <key>missonary</key>
+        <string>missionary</string>
+        <key>misterious</key>
+        <string>mysterious</string>
+        <key>mistery</key>
+        <string>mystery</string>
+        <key>misteryous</key>
+        <string>mysterious</string>
+        <key>mkae</key>
+        <string>make</string>
+        <key>mkaes</key>
+        <string>makes</string>
+        <key>mkaing</key>
+        <string>making</string>
+        <key>mkea</key>
+        <string>make</string>
+        <key>moderm</key>
+        <string>modem</string>
+        <key>modle</key>
+        <string>model</string>
+        <key>moent</key>
+        <string>moment</string>
+        <key>moeny</key>
+        <string>money</string>
+        <key>mohammedans</key>
+        <string>muslims</string>
+        <key>moil</key>
+        <string>soil</string>
+        <key>moleclues</key>
+        <string>molecules</string>
+        <key>momento</key>
+        <string>memento</string>
+        <key>monestaries</key>
+        <string>monasteries</string>
+        <key>monestary</key>
+        <string>monastery</string>
+        <key>monickers</key>
+        <string>monikers</string>
+        <key>monolite</key>
+        <string>monolithic</string>
+        <key>montains</key>
+        <string>mountains</string>
+        <key>montanous</key>
+        <string>mountainous</string>
+        <key>monts</key>
+        <string>months</string>
+        <key>montypic</key>
+        <string>monotypic</string>
+        <key>moreso</key>
+        <string>more so</string>
+        <key>morgage</key>
+        <string>mortgage</string>
+        <key>morroccan</key>
+        <string>moroccan</string>
+        <key>morrocco</key>
+        <string>morocco</string>
+        <key>morroco</key>
+        <string>morocco</string>
+        <key>mortage</key>
+        <string>mortgage</string>
+        <key>mosture</key>
+        <string>moisture</string>
+        <key>motiviated</key>
+        <string>motivated</string>
+        <key>mounth</key>
+        <string>month</string>
+        <key>movei</key>
+        <string>movie</string>
+        <key>movment</key>
+        <string>movement</string>
+        <key>mroe</key>
+        <string>more</string>
+        <key>mucuous</key>
+        <string>mucous</string>
+        <key>muder</key>
+        <string>murder</string>
+        <key>mudering</key>
+        <string>murdering</string>
+        <key>muhammadan</key>
+        <string>muslim</string>
+        <key>multicultralism</key>
+        <string>multiculturalism</string>
+        <key>multipled</key>
+        <string>multiplied</string>
+        <key>multiplers</key>
+        <string>multipliers</string>
+        <key>munbers</key>
+        <string>numbers</string>
+        <key>muncipalities</key>
+        <string>municipalities</string>
+        <key>muncipality</key>
+        <string>municipality</string>
+        <key>munnicipality</key>
+        <string>municipality</string>
+        <key>muscels</key>
+        <string>muscles</string>
+        <key>muscial</key>
+        <string>musical</string>
+        <key>muscician</key>
+        <string>musician</string>
+        <key>muscicians</key>
+        <string>musicians</string>
+        <key>mutiliated</key>
+        <string>mutilated</string>
+        <key>myraid</key>
+        <string>myriad</string>
+        <key>mysef</key>
+        <string>myself</string>
+        <key>mysogynist</key>
+        <string>misogynist</string>
+        <key>mysogyny</key>
+        <string>misogyny</string>
+        <key>mysterous</key>
+        <string>mysterious</string>
+        <key>naieve</key>
+        <string>naive</string>
+        <key>naturaly</key>
+        <string>naturally</string>
+        <key>naturely</key>
+        <string>naturally</string>
+        <key>naturual</key>
+        <string>natural</string>
+        <key>naturually</key>
+        <string>naturally</string>
+        <key>neccesarily</key>
+        <string>necessarily</string>
+        <key>neccesary</key>
+        <string>necessary</string>
+        <key>neccessarily</key>
+        <string>necessarily</string>
+        <key>neccessary</key>
+        <string>necessary</string>
+        <key>neccessities</key>
+        <string>necessities</string>
+        <key>necesarily</key>
+        <string>necessarily</string>
+        <key>necesary</key>
+        <string>necessary</string>
+        <key>necessiate</key>
+        <string>necessitate</string>
+        <key>neglible</key>
+        <string>negligible</string>
+        <key>negligable</key>
+        <string>negligible</string>
+        <key>negociate</key>
+        <string>negotiate</string>
+        <key>negociation</key>
+        <string>negotiation</string>
+        <key>negociations</key>
+        <string>negotiations</string>
+        <key>negotation</key>
+        <string>negotiation</string>
+        <key>neice</key>
+        <string>niece</string>
+        <key>neigborhood</key>
+        <string>neighborhood</string>
+        <key>neigbour</key>
+        <string>neighbour</string>
+        <key>neigbourhood</key>
+        <string>neighbourhood</string>
+        <key>neolitic</key>
+        <string>neolithic</string>
+        <key>nessasarily</key>
+        <string>necessarily</string>
+        <key>nessecary</key>
+        <string>necessary</string>
+        <key>nestin</key>
+        <string>nesting</string>
+        <key>neverthless</key>
+        <string>nevertheless</string>
+        <key>newletters</key>
+        <string>newsletters</string>
+        <key>nickle</key>
+        <string>nickel</string>
+        <key>nightfa;;</key>
+        <string>nightfall</string>
+        <key>nightime</key>
+        <string>nighttime</string>
+        <key>nineth</key>
+        <string>ninth</string>
+        <key>ninteenth</key>
+        <string>nineteenth</string>
+        <key>ninties</key>
+        <string>1990s</string>
+        <key>ninty</key>
+        <string>ninety</string>
+        <key>nkow</key>
+        <string>know</string>
+        <key>nkwo</key>
+        <string>know</string>
+        <key>nmae</key>
+        <string>name</string>
+        <key>noncombatents</key>
+        <string>noncombatants</string>
+        <key>nonsence</key>
+        <string>nonsense</string>
+        <key>nontheless</key>
+        <string>nonetheless</string>
+        <key>noone</key>
+        <string>no one</string>
+        <key>norhern</key>
+        <string>northern</string>
+        <key>northen</key>
+        <string>northern</string>
+        <key>northereastern</key>
+        <string>northeastern</string>
+        <key>notabley</key>
+        <string>notably</string>
+        <key>noteable</key>
+        <string>notable</string>
+        <key>noteably</key>
+        <string>notably</string>
+        <key>noteriety</key>
+        <string>notoriety</string>
+        <key>noth</key>
+        <string>north</string>
+        <key>nothern</key>
+        <string>northern</string>
+        <key>noticable</key>
+        <string>noticeable</string>
+        <key>noticably</key>
+        <string>noticeably</string>
+        <key>noticeing</key>
+        <string>noticing</string>
+        <key>noticible</key>
+        <string>noticeable</string>
+        <key>notwhithstanding</key>
+        <string>notwithstanding</string>
+        <key>noveau</key>
+        <string>nouveau</string>
+        <key>nowdays</key>
+        <string>nowadays</string>
+        <key>nowe</key>
+        <string>now</string>
+        <key>nto</key>
+        <string>not</string>
+        <key>nucular</key>
+        <string>nuclear</string>
+        <key>nuculear</key>
+        <string>nuclear</string>
+        <key>nuisanse</key>
+        <string>nuisance</string>
+        <key>numberous</key>
+        <string>numerous</string>
+        <key>nusance</key>
+        <string>nuisance</string>
+        <key>nutritent</key>
+        <string>nutrient</string>
+        <key>nutritents</key>
+        <string>nutrients</string>
+        <key>nuturing</key>
+        <string>nurturing</string>
+        <key>obediance</key>
+        <string>obedience</string>
+        <key>obediant</key>
+        <string>obedient</string>
+        <key>obession</key>
+        <string>obsession</string>
+        <key>obssessed</key>
+        <string>obsessed</string>
+        <key>obstacal</key>
+        <string>obstacle</string>
+        <key>obstancles</key>
+        <string>obstacles</string>
+        <key>obstruced</key>
+        <string>obstructed</string>
+        <key>ocasion</key>
+        <string>occasion</string>
+        <key>ocasional</key>
+        <string>occasional</string>
+        <key>ocasionally</key>
+        <string>occasionally</string>
+        <key>ocasionaly</key>
+        <string>occasionally</string>
+        <key>ocasioned</key>
+        <string>occasioned</string>
+        <key>ocasions</key>
+        <string>occasions</string>
+        <key>ocassion</key>
+        <string>occasion</string>
+        <key>ocassional</key>
+        <string>occasional</string>
+        <key>ocassionally</key>
+        <string>occasionally</string>
+        <key>ocassionaly</key>
+        <string>occasionally</string>
+        <key>ocassioned</key>
+        <string>occasioned</string>
+        <key>ocassions</key>
+        <string>occasions</string>
+        <key>occaison</key>
+        <string>occasion</string>
+        <key>occassion</key>
+        <string>occasion</string>
+        <key>occassional</key>
+        <string>occasional</string>
+        <key>occassionally</key>
+        <string>occasionally</string>
+        <key>occassionaly</key>
+        <string>occasionally</string>
+        <key>occassioned</key>
+        <string>occasioned</string>
+        <key>occassions</key>
+        <string>occasions</string>
+        <key>occationally</key>
+        <string>occasionally</string>
+        <key>occour</key>
+        <string>occur</string>
+        <key>occurance</key>
+        <string>occurrence</string>
+        <key>occurances</key>
+        <string>occurrences</string>
+        <key>occured</key>
+        <string>occurred</string>
+        <key>occurence</key>
+        <string>occurrence</string>
+        <key>occurences</key>
+        <string>occurrences</string>
+        <key>occuring</key>
+        <string>occurring</string>
+        <key>occurr</key>
+        <string>occur</string>
+        <key>occurrance</key>
+        <string>occurrence</string>
+        <key>occurrances</key>
+        <string>occurrences</string>
+        <key>octohedra</key>
+        <string>octahedra</string>
+        <key>octohedral</key>
+        <string>octahedral</string>
+        <key>octohedron</key>
+        <string>octahedron</string>
+        <key>ocuntries</key>
+        <string>countries</string>
+        <key>ocuntry</key>
+        <string>country</string>
+        <key>ocurr</key>
+        <string>occur</string>
+        <key>ocurrance</key>
+        <string>occurrence</string>
+        <key>ocurred</key>
+        <string>occurred</string>
+        <key>ocurrence</key>
+        <string>occurrence</string>
+        <key>offcers</key>
+        <string>officers</string>
+        <key>offcially</key>
+        <string>officially</string>
+        <key>offereings</key>
+        <string>offerings</string>
+        <key>offical</key>
+        <string>official</string>
+        <key>offically</key>
+        <string>officially</string>
+        <key>officals</key>
+        <string>officials</string>
+        <key>officaly</key>
+        <string>officially</string>
+        <key>officialy</key>
+        <string>officially</string>
+        <key>offred</key>
+        <string>offered</string>
+        <key>oftenly</key>
+        <string>often</string>
+        <key>oging</key>
+        <string>going</string>
+        <key>omision</key>
+        <string>omission</string>
+        <key>omited</key>
+        <string>omitted</string>
+        <key>omiting</key>
+        <string>omitting</string>
+        <key>omlette</key>
+        <string>omelette</string>
+        <key>ommision</key>
+        <string>omission</string>
+        <key>ommited</key>
+        <string>omitted</string>
+        <key>ommiting</key>
+        <string>omitting</string>
+        <key>ommitted</key>
+        <string>omitted</string>
+        <key>ommitting</key>
+        <string>omitting</string>
+        <key>omniverous</key>
+        <string>omnivorous</string>
+        <key>omniverously</key>
+        <string>omnivorously</string>
+        <key>omre</key>
+        <string>more</string>
+        <key>onot</key>
+        <string>note</string>
+        <key>onxy</key>
+        <string>onyx</string>
+        <key>onyl</key>
+        <string>only</string>
+        <key>openess</key>
+        <string>openness</string>
+        <key>oponent</key>
+        <string>opponent</string>
+        <key>oportunity</key>
+        <string>opportunity</string>
+        <key>opose</key>
+        <string>oppose</string>
+        <key>oposite</key>
+        <string>opposite</string>
+        <key>oposition</key>
+        <string>opposition</string>
+        <key>oppenly</key>
+        <string>openly</string>
+        <key>oppinion</key>
+        <string>opinion</string>
+        <key>opponant</key>
+        <string>opponent</string>
+        <key>oppononent</key>
+        <string>opponent</string>
+        <key>oppositition</key>
+        <string>opposition</string>
+        <key>oppossed</key>
+        <string>opposed</string>
+        <key>opprotunity</key>
+        <string>opportunity</string>
+        <key>opression</key>
+        <string>oppression</string>
+        <key>opressive</key>
+        <string>oppressive</string>
+        <key>opthalmic</key>
+        <string>ophthalmic</string>
+        <key>opthalmologist</key>
+        <string>ophthalmologist</string>
+        <key>opthalmology</key>
+        <string>ophthalmology</string>
+        <key>opthamologist</key>
+        <string>ophthalmologist</string>
+        <key>optmizations</key>
+        <string>optimizations</string>
+        <key>optomism</key>
+        <string>optimism</string>
+        <key>orded</key>
+        <string>ordered</string>
+        <key>organim</key>
+        <string>organism</string>
+        <key>organistion</key>
+        <string>organisation</string>
+        <key>organiztion</key>
+        <string>organization</string>
+        <key>orgin</key>
+        <string>origin</string>
+        <key>orginal</key>
+        <string>original</string>
+        <key>orginally</key>
+        <string>originally</string>
+        <key>orginize</key>
+        <string>organise</string>
+        <key>oridinarily</key>
+        <string>ordinarily</string>
+        <key>origanaly</key>
+        <string>originally</string>
+        <key>originall</key>
+        <string>original</string>
+        <key>originaly</key>
+        <string>originally</string>
+        <key>originially</key>
+        <string>originally</string>
+        <key>originnally</key>
+        <string>originally</string>
+        <key>origional</key>
+        <string>original</string>
+        <key>orignally</key>
+        <string>originally</string>
+        <key>orignially</key>
+        <string>originally</string>
+        <key>otehr</key>
+        <string>other</string>
+        <key>oublisher</key>
+        <string>publisher</string>
+        <key>ouevre</key>
+        <string>oeuvre</string>
+        <key>oustanding</key>
+        <string>outstanding</string>
+        <key>overshaddowed</key>
+        <string>overshadowed</string>
+        <key>overthere</key>
+        <string>over there</string>
+        <key>overwelming</key>
+        <string>overwhelming</string>
+        <key>overwheliming</key>
+        <string>overwhelming</string>
+        <key>owrk</key>
+        <string>work</string>
+        <key>owudl</key>
+        <string>would</string>
+        <key>oxigen</key>
+        <string>oxygen</string>
+        <key>oximoron</key>
+        <string>oxymoron</string>
+        <key>p0enis</key>
+        <string>penis</string>
+        <key>paide</key>
+        <string>paid</string>
+        <key>paitience</key>
+        <string>patience</string>
+        <key>palce</key>
+        <string>place</string>
+        <key>paleolitic</key>
+        <string>paleolithic</string>
+        <key>paliamentarian</key>
+        <string>parliamentarian</string>
+        <key>pallete</key>
+        <string>palette</string>
+        <key>pamflet</key>
+        <string>pamphlet</string>
+        <key>pamplet</key>
+        <string>pamphlet</string>
+        <key>pantomine</key>
+        <string>pantomime</string>
+        <key>paralel</key>
+        <string>parallel</string>
+        <key>paralell</key>
+        <string>parallel</string>
+        <key>paralelly</key>
+        <string>parallelly</string>
+        <key>paralely</key>
+        <string>parallelly</string>
+        <key>parallely</key>
+        <string>parallelly</string>
+        <key>paranthesis</key>
+        <string>parenthesis</string>
+        <key>paraphenalia</key>
+        <string>paraphernalia</string>
+        <key>parellels</key>
+        <string>parallels</string>
+        <key>parituclar</key>
+        <string>particular</string>
+        <key>parliment</key>
+        <string>parliament</string>
+        <key>parrakeets</key>
+        <string>parakeets</string>
+        <key>parralel</key>
+        <string>parallel</string>
+        <key>parrallel</key>
+        <string>parallel</string>
+        <key>parrallell</key>
+        <string>parallel</string>
+        <key>parrallelly</key>
+        <string>parallelly</string>
+        <key>parrallely</key>
+        <string>parallelly</string>
+        <key>partialy</key>
+        <string>partially</string>
+        <key>particually</key>
+        <string>particularly</string>
+        <key>particualr</key>
+        <string>particular</string>
+        <key>particuarly</key>
+        <string>particularly</string>
+        <key>particularily</key>
+        <string>particularly</string>
+        <key>particulary</key>
+        <string>particularly</string>
+        <key>pary</key>
+        <string>party</string>
+        <key>pased</key>
+        <string>passed</string>
+        <key>pasengers</key>
+        <string>passengers</string>
+        <key>passerbys</key>
+        <string>passersby</string>
+        <key>pasttime</key>
+        <string>pastime</string>
+        <key>pastural</key>
+        <string>pastoral</string>
+        <key>paticular</key>
+        <string>particular</string>
+        <key>pattented</key>
+        <string>patented</string>
+        <key>pavillion</key>
+        <string>pavilion</string>
+        <key>payed</key>
+        <string>paid</string>
+        <key>pblisher</key>
+        <string>publisher</string>
+        <key>pbulisher</key>
+        <string>publisher</string>
+        <key>peacefuland</key>
+        <string>peaceful and</string>
+        <key>peageant</key>
+        <string>pageant</string>
+        <key>peculure</key>
+        <string>peculiar</string>
+        <key>pedestrain</key>
+        <string>pedestrian</string>
+        <key>peformed</key>
+        <string>performed</string>
+        <key>peice</key>
+        <string>piece</string>
+        <key>penatly</key>
+        <string>penalty</string>
+        <key>penerator</key>
+        <string>penetrator</string>
+        <key>penisula</key>
+        <string>peninsula</string>
+        <key>penisular</key>
+        <string>peninsular</string>
+        <key>penninsula</key>
+        <string>peninsula</string>
+        <key>penninsular</key>
+        <string>peninsular</string>
+        <key>pennisula</key>
+        <string>peninsula</string>
+        <key>pensinula</key>
+        <string>peninsula</string>
+        <key>peom</key>
+        <string>poem</string>
+        <key>peoms</key>
+        <string>poems</string>
+        <key>peopel</key>
+        <string>people</string>
+        <key>peotry</key>
+        <string>poetry</string>
+        <key>perade</key>
+        <string>parade</string>
+        <key>percepted</key>
+        <string>perceived</string>
+        <key>percieve</key>
+        <string>perceive</string>
+        <key>percieved</key>
+        <string>perceived</string>
+        <key>perenially</key>
+        <string>perennially</string>
+        <key>perfomance</key>
+        <string>performance</string>
+        <key>perfomers</key>
+        <string>performers</string>
+        <key>performence</key>
+        <string>performance</string>
+        <key>performes</key>
+        <string>performed</string>
+        <key>perhasp</key>
+        <string>perhaps</string>
+        <key>perheaps</key>
+        <string>perhaps</string>
+        <key>perhpas</key>
+        <string>perhaps</string>
+        <key>peripathetic</key>
+        <string>peripatetic</string>
+        <key>peristent</key>
+        <string>persistent</string>
+        <key>perjery</key>
+        <string>perjury</string>
+        <key>perjorative</key>
+        <string>pejorative</string>
+        <key>permanant</key>
+        <string>permanent</string>
+        <key>permenant</key>
+        <string>permanent</string>
+        <key>permenantly</key>
+        <string>permanently</string>
+        <key>permissable</key>
+        <string>permissible</string>
+        <key>perogative</key>
+        <string>prerogative</string>
+        <key>peronal</key>
+        <string>personal</string>
+        <key>perosnality</key>
+        <string>personality</string>
+        <key>perphas</key>
+        <string>perhaps</string>
+        <key>perpindicular</key>
+        <string>perpendicular</string>
+        <key>perseverence</key>
+        <string>perseverance</string>
+        <key>persistance</key>
+        <string>persistence</string>
+        <key>persistant</key>
+        <string>persistent</string>
+        <key>personel</key>
+        <string>personnel</string>
+        <key>personell</key>
+        <string>personnel</string>
+        <key>personnell</key>
+        <string>personnel</string>
+        <key>persuded</key>
+        <string>persuaded</string>
+        <key>persue</key>
+        <string>pursue</string>
+        <key>persued</key>
+        <string>pursued</string>
+        <key>persuing</key>
+        <string>pursuing</string>
+        <key>persuit</key>
+        <string>pursuit</string>
+        <key>persuits</key>
+        <string>pursuits</string>
+        <key>pertubation</key>
+        <string>perturbation</string>
+        <key>pertubations</key>
+        <string>perturbations</string>
+        <key>pessiary</key>
+        <string>pessary</string>
+        <key>petetion</key>
+        <string>petition</string>
+        <key>phenomenom</key>
+        <string>phenomenon</string>
+        <key>phenomenonal</key>
+        <string>phenomenal</string>
+        <key>phenomenonly</key>
+        <string>phenomenally</string>
+        <key>phenomonenon</key>
+        <string>phenomenon</string>
+        <key>phenomonon</key>
+        <string>phenomenon</string>
+        <key>phenonmena</key>
+        <string>phenomena</string>
+        <key>philisopher</key>
+        <string>philosopher</string>
+        <key>philisophical</key>
+        <string>philosophical</string>
+        <key>philisophy</key>
+        <string>philosophy</string>
+        <key>phillosophically</key>
+        <string>philosophically</string>
+        <key>philospher</key>
+        <string>philosopher</string>
+        <key>philosphies</key>
+        <string>philosophies</string>
+        <key>philosphy</key>
+        <string>philosophy</string>
+        <key>phongraph</key>
+        <string>phonograph</string>
+        <key>phylosophical</key>
+        <string>philosophical</string>
+        <key>physicaly</key>
+        <string>physically</string>
+        <key>piblisher</key>
+        <string>publisher</string>
+        <key>pich</key>
+        <string>pitch</string>
+        <key>pilgrimmage</key>
+        <string>pilgrimage</string>
+        <key>pilgrimmages</key>
+        <string>pilgrimages</string>
+        <key>pinapple</key>
+        <string>pineapple</string>
+        <key>pinnaple</key>
+        <string>pineapple</string>
+        <key>pinoneered</key>
+        <string>pioneered</string>
+        <key>plagarism</key>
+        <string>plagiarism</string>
+        <key>planation</key>
+        <string>plantation</string>
+        <key>planed</key>
+        <string>planned</string>
+        <key>plantiff</key>
+        <string>plaintiff</string>
+        <key>plateu</key>
+        <string>plateau</string>
+        <key>plausable</key>
+        <string>plausible</string>
+        <key>playright</key>
+        <string>playwright</string>
+        <key>playwrite</key>
+        <string>playwright</string>
+        <key>playwrites</key>
+        <string>playwrights</string>
+        <key>pleasent</key>
+        <string>pleasant</string>
+        <key>plebicite</key>
+        <string>plebiscite</string>
+        <key>plesant</key>
+        <string>pleasant</string>
+        <key>poenis</key>
+        <string>penis</string>
+        <key>poeoples</key>
+        <string>peoples</string>
+        <key>poety</key>
+        <string>poetry</string>
+        <key>poisin</key>
+        <string>poison</string>
+        <key>polical</key>
+        <string>political</string>
+        <key>polinator</key>
+        <string>pollinator</string>
+        <key>polinators</key>
+        <string>pollinators</string>
+        <key>politican</key>
+        <string>politician</string>
+        <key>politicans</key>
+        <string>politicians</string>
+        <key>poltical</key>
+        <string>political</string>
+        <key>polute</key>
+        <string>pollute</string>
+        <key>poluted</key>
+        <string>polluted</string>
+        <key>polutes</key>
+        <string>pollutes</string>
+        <key>poluting</key>
+        <string>polluting</string>
+        <key>polution</key>
+        <string>pollution</string>
+        <key>polyphonyic</key>
+        <string>polyphonic</string>
+        <key>polysaccaride</key>
+        <string>polysaccharide</string>
+        <key>polysaccharid</key>
+        <string>polysaccharide</string>
+        <key>pomegranite</key>
+        <string>pomegranate</string>
+        <key>pomotion</key>
+        <string>promotion</string>
+        <key>poportional</key>
+        <string>proportional</string>
+        <key>popoulation</key>
+        <string>population</string>
+        <key>popularaty</key>
+        <string>popularity</string>
+        <key>populare</key>
+        <string>popular</string>
+        <key>populer</key>
+        <string>popular</string>
+        <key>portait</key>
+        <string>portrait</string>
+        <key>portayed</key>
+        <string>portrayed</string>
+        <key>portraing</key>
+        <string>portraying</string>
+        <key>portuguease</key>
+        <string>portuguese</string>
+        <key>portugues</key>
+        <string>Portuguese</string>
+        <key>posess</key>
+        <string>possess</string>
+        <key>posessed</key>
+        <string>possessed</string>
+        <key>posesses</key>
+        <string>possesses</string>
+        <key>posessing</key>
+        <string>possessing</string>
+        <key>posession</key>
+        <string>possession</string>
+        <key>posessions</key>
+        <string>possessions</string>
+        <key>posion</key>
+        <string>poison</string>
+        <key>positon</key>
+        <string>position</string>
+        <key>possable</key>
+        <string>possible</string>
+        <key>possably</key>
+        <string>possibly</string>
+        <key>posseses</key>
+        <string>possesses</string>
+        <key>possesing</key>
+        <string>possessing</string>
+        <key>possesion</key>
+        <string>possession</string>
+        <key>possessess</key>
+        <string>possesses</string>
+        <key>possibile</key>
+        <string>possible</string>
+        <key>possibilty</key>
+        <string>possibility</string>
+        <key>possiblility</key>
+        <string>possibility</string>
+        <key>possiblilty</key>
+        <string>possibility</string>
+        <key>possiblities</key>
+        <string>possibilities</string>
+        <key>possiblity</key>
+        <string>possibility</string>
+        <key>possition</key>
+        <string>position</string>
+        <key>posthomous</key>
+        <string>posthumous</string>
+        <key>postion</key>
+        <string>position</string>
+        <key>postive</key>
+        <string>positive</string>
+        <key>potatos</key>
+        <string>potatoes</string>
+        <key>potrait</key>
+        <string>portrait</string>
+        <key>potrayed</key>
+        <string>portrayed</string>
+        <key>poulations</key>
+        <string>populations</string>
+        <key>poverful</key>
+        <string>powerful</string>
+        <key>poweful</key>
+        <string>powerful</string>
+        <key>powerfull</key>
+        <string>powerful</string>
+        <key>ppublisher</key>
+        <string>publisher</string>
+        <key>practial</key>
+        <string>practical</string>
+        <key>practially</key>
+        <string>practically</string>
+        <key>practicaly</key>
+        <string>practically</string>
+        <key>practicioner</key>
+        <string>practitioner</string>
+        <key>practicioners</key>
+        <string>practitioners</string>
+        <key>practicly</key>
+        <string>practically</string>
+        <key>practioner</key>
+        <string>practitioner</string>
+        <key>practioners</key>
+        <string>practitioners</string>
+        <key>prairy</key>
+        <string>prairie</string>
+        <key>prarie</key>
+        <string>prairie</string>
+        <key>praries</key>
+        <string>prairies</string>
+        <key>pratice</key>
+        <string>practice</string>
+        <key>preample</key>
+        <string>preamble</string>
+        <key>precedessor</key>
+        <string>predecessor</string>
+        <key>preceed</key>
+        <string>precede</string>
+        <key>preceeded</key>
+        <string>preceded</string>
+        <key>preceeding</key>
+        <string>preceding</string>
+        <key>preceeds</key>
+        <string>precedes</string>
+        <key>precentage</key>
+        <string>percentage</string>
+        <key>precice</key>
+        <string>precise</string>
+        <key>precisly</key>
+        <string>precisely</string>
+        <key>precurser</key>
+        <string>precursor</string>
+        <key>predecesors</key>
+        <string>predecessors</string>
+        <key>predicatble</key>
+        <string>predictable</string>
+        <key>predicitons</key>
+        <string>predictions</string>
+        <key>predomiantly</key>
+        <string>predominately</string>
+        <key>prefered</key>
+        <string>preferred</string>
+        <key>prefering</key>
+        <string>preferring</string>
+        <key>preferrably</key>
+        <string>preferably</string>
+        <key>pregancies</key>
+        <string>pregnancies</string>
+        <key>preiod</key>
+        <string>period</string>
+        <key>preliferation</key>
+        <string>proliferation</string>
+        <key>premeire</key>
+        <string>premiere</string>
+        <key>premeired</key>
+        <string>premiered</string>
+        <key>premillenial</key>
+        <string>premillennial</string>
+        <key>preminence</key>
+        <string>preeminence</string>
+        <key>premission</key>
+        <string>permission</string>
+        <key>preocupation</key>
+        <string>preoccupation</string>
+        <key>prepair</key>
+        <string>prepare</string>
+        <key>prepartion</key>
+        <string>preparation</string>
+        <key>prepatory</key>
+        <string>preparatory</string>
+        <key>preperation</key>
+        <string>preparation</string>
+        <key>preperations</key>
+        <string>preparations</string>
+        <key>preriod</key>
+        <string>period</string>
+        <key>presedential</key>
+        <string>presidential</string>
+        <key>presense</key>
+        <string>presence</string>
+        <key>presidenital</key>
+        <string>presidential</string>
+        <key>presidental</key>
+        <string>presidential</string>
+        <key>presitgious</key>
+        <string>prestigious</string>
+        <key>prespective</key>
+        <string>perspective</string>
+        <key>prestigeous</key>
+        <string>prestigious</string>
+        <key>prestigous</key>
+        <string>prestigious</string>
+        <key>presumabely</key>
+        <string>presumably</string>
+        <key>presumibly</key>
+        <string>presumably</string>
+        <key>pretection</key>
+        <string>protection</string>
+        <key>prevelant</key>
+        <string>prevalent</string>
+        <key>preverse</key>
+        <string>perverse</string>
+        <key>previvous</key>
+        <string>previous</string>
+        <key>pricipal</key>
+        <string>principal</string>
+        <key>priciple</key>
+        <string>principle</string>
+        <key>priestood</key>
+        <string>priesthood</string>
+        <key>primarly</key>
+        <string>primarily</string>
+        <key>primative</key>
+        <string>primitive</string>
+        <key>primatively</key>
+        <string>primitively</string>
+        <key>primatives</key>
+        <string>primitives</string>
+        <key>primordal</key>
+        <string>primordial</string>
+        <key>priveledges</key>
+        <string>privileges</string>
+        <key>privelege</key>
+        <string>privilege</string>
+        <key>priveleged</key>
+        <string>privileged</string>
+        <key>priveleges</key>
+        <string>privileges</string>
+        <key>privelige</key>
+        <string>privilege</string>
+        <key>priveliged</key>
+        <string>privileged</string>
+        <key>priveliges</key>
+        <string>privileges</string>
+        <key>privelleges</key>
+        <string>privileges</string>
+        <key>privilage</key>
+        <string>privilege</string>
+        <key>priviledge</key>
+        <string>privilege</string>
+        <key>priviledges</key>
+        <string>privileges</string>
+        <key>privledge</key>
+        <string>privilege</string>
+        <key>privte</key>
+        <string>private</string>
+        <key>probabilaty</key>
+        <string>probability</string>
+        <key>probablistic</key>
+        <string>probabilistic</string>
+        <key>probablly</key>
+        <string>probably</string>
+        <key>probalibity</key>
+        <string>probability</string>
+        <key>probaly</key>
+        <string>probably</string>
+        <key>probelm</key>
+        <string>problem</string>
+        <key>proccess</key>
+        <string>process</string>
+        <key>proccessing</key>
+        <string>processing</string>
+        <key>procede</key>
+        <string>proceed</string>
+        <key>proceded</key>
+        <string>proceeded</string>
+        <key>procedes</key>
+        <string>proceeds</string>
+        <key>procedger</key>
+        <string>procedure</string>
+        <key>proceding</key>
+        <string>proceeding</string>
+        <key>procedings</key>
+        <string>proceedings</string>
+        <key>proceedure</key>
+        <string>procedure</string>
+        <key>proces</key>
+        <string>process</string>
+        <key>processer</key>
+        <string>processor</string>
+        <key>proclaimation</key>
+        <string>proclamation</string>
+        <key>proclamed</key>
+        <string>proclaimed</string>
+        <key>proclaming</key>
+        <string>proclaiming</string>
+        <key>proclomation</key>
+        <string>proclamation</string>
+        <key>profesion</key>
+        <string>profession</string>
+        <key>profesor</key>
+        <string>professor</string>
+        <key>professer</key>
+        <string>professor</string>
+        <key>proffesed</key>
+        <string>professed</string>
+        <key>proffesion</key>
+        <string>profession</string>
+        <key>proffesional</key>
+        <string>professional</string>
+        <key>proffesor</key>
+        <string>professor</string>
+        <key>profilic</key>
+        <string>prolific</string>
+        <key>progessed</key>
+        <string>progressed</string>
+        <key>programable</key>
+        <string>programmable</string>
+        <key>progrom</key>
+        <string>program</string>
+        <key>progroms</key>
+        <string>programs</string>
+        <key>prohabition</key>
+        <string>prohibition</string>
+        <key>prologomena</key>
+        <string>prolegomena</string>
+        <key>prominance</key>
+        <string>prominence</string>
+        <key>prominant</key>
+        <string>prominent</string>
+        <key>prominantly</key>
+        <string>prominently</string>
+        <key>prominately</key>
+        <string>prominently</string>
+        <key>promiscous</key>
+        <string>promiscuous</string>
+        <key>promotted</key>
+        <string>promoted</string>
+        <key>pronomial</key>
+        <string>pronominal</string>
+        <key>pronouced</key>
+        <string>pronounced</string>
+        <key>pronounched</key>
+        <string>pronounced</string>
+        <key>pronounciation</key>
+        <string>pronunciation</string>
+        <key>proove</key>
+        <string>prove</string>
+        <key>prooved</key>
+        <string>proved</string>
+        <key>prophacy</key>
+        <string>prophecy</string>
+        <key>propietary</key>
+        <string>proprietary</string>
+        <key>propmted</key>
+        <string>prompted</string>
+        <key>propoganda</key>
+        <string>propaganda</string>
+        <key>propogate</key>
+        <string>propagate</string>
+        <key>propogates</key>
+        <string>propagates</string>
+        <key>propogation</key>
+        <string>propagation</string>
+        <key>propostion</key>
+        <string>proposition</string>
+        <key>propotions</key>
+        <string>proportions</string>
+        <key>propper</key>
+        <string>proper</string>
+        <key>propperly</key>
+        <string>properly</string>
+        <key>proprietory</key>
+        <string>proprietary</string>
+        <key>proseletyzing</key>
+        <string>proselytizing</string>
+        <key>protaganist</key>
+        <string>protagonist</string>
+        <key>protaganists</key>
+        <string>protagonists</string>
+        <key>protocal</key>
+        <string>protocol</string>
+        <key>protoganist</key>
+        <string>protagonist</string>
+        <key>protrayed</key>
+        <string>portrayed</string>
+        <key>protruberance</key>
+        <string>protuberance</string>
+        <key>protruberances</key>
+        <string>protuberances</string>
+        <key>prouncements</key>
+        <string>pronouncements</string>
+        <key>provacative</key>
+        <string>provocative</string>
+        <key>provded</key>
+        <string>provided</string>
+        <key>provicial</key>
+        <string>provincial</string>
+        <key>provinicial</key>
+        <string>provincial</string>
+        <key>provisiosn</key>
+        <string>provision</string>
+        <key>provisonal</key>
+        <string>provisional</string>
+        <key>proximty</key>
+        <string>proximity</string>
+        <key>pseudononymous</key>
+        <string>pseudonymous</string>
+        <key>pseudonyn</key>
+        <string>pseudonym</string>
+        <key>psuedo</key>
+        <string>pseudo</string>
+        <key>psycology</key>
+        <string>psychology</string>
+        <key>psyhic</key>
+        <string>psychic</string>
+        <key>pubilsher</key>
+        <string>publisher</string>
+        <key>pubisher</key>
+        <string>publisher</string>
+        <key>publiaher</key>
+        <string>publisher</string>
+        <key>publically</key>
+        <string>publicly</string>
+        <key>publicaly</key>
+        <string>publicly</string>
+        <key>publicher</key>
+        <string>publisher</string>
+        <key>publihser</key>
+        <string>publisher</string>
+        <key>publisehr</key>
+        <string>publisher</string>
+        <key>publiser</key>
+        <string>publisher</string>
+        <key>publisger</key>
+        <string>publisher</string>
+        <key>publisheed</key>
+        <string>published</string>
+        <key>publisherr</key>
+        <string>publisher</string>
+        <key>publishher</key>
+        <string>publisher</string>
+        <key>publishor</key>
+        <string>publisher</string>
+        <key>publishre</key>
+        <string>publisher</string>
+        <key>publissher</key>
+        <string>publisher</string>
+        <key>publlisher</key>
+        <string>publisher</string>
+        <key>publsiher</key>
+        <string>publisher</string>
+        <key>publusher</key>
+        <string>publisher</string>
+        <key>puchasing</key>
+        <string>purchasing</string>
+        <key>pulisher</key>
+        <string>publisher</string>
+        <key>pumkin</key>
+        <string>pumpkin</string>
+        <key>puplisher</key>
+        <string>publisher</string>
+        <key>puritannical</key>
+        <string>puritanical</string>
+        <key>purposedly</key>
+        <string>purposely</string>
+        <key>purpotedly</key>
+        <string>purportedly</string>
+        <key>pursuade</key>
+        <string>persuade</string>
+        <key>pursuaded</key>
+        <string>persuaded</string>
+        <key>pursuades</key>
+        <string>persuades</string>
+        <key>pususading</key>
+        <string>persuading</string>
+        <key>puting</key>
+        <string>putting</string>
+        <key>pwoer</key>
+        <string>power</string>
+        <key>pyscic</key>
+        <string>psychic</string>
+        <key>qtuie</key>
+        <string>quiet</string>
+        <key>quantaty</key>
+        <string>quantity</string>
+        <key>quantitiy</key>
+        <string>quantity</string>
+        <key>quarantaine</key>
+        <string>quarantine</string>
+        <key>questonable</key>
+        <string>questionable</string>
+        <key>quicklyu</key>
+        <string>quickly</string>
+        <key>quinessential</key>
+        <string>quintessential</string>
+        <key>quitted</key>
+        <string>quit</string>
+        <key>quizes</key>
+        <string>quizzes</string>
+        <key>qutie</key>
+        <string>quiet</string>
+        <key>rabinnical</key>
+        <string>rabbinical</string>
+        <key>racaus</key>
+        <string>raucous</string>
+        <key>radiactive</key>
+        <string>radioactive</string>
+        <key>radify</key>
+        <string>ratify</string>
+        <key>raelly</key>
+        <string>really</string>
+        <key>rarified</key>
+        <string>rarefied</string>
+        <key>reaccurring</key>
+        <string>recurring</string>
+        <key>reacing</key>
+        <string>reaching</string>
+        <key>reacll</key>
+        <string>recall</string>
+        <key>readmition</key>
+        <string>readmission</string>
+        <key>realitvely</key>
+        <string>relatively</string>
+        <key>realsitic</key>
+        <string>realistic</string>
+        <key>realtions</key>
+        <string>relations</string>
+        <key>realy</key>
+        <string>really</string>
+        <key>realyl</key>
+        <string>really</string>
+        <key>reasearch</key>
+        <string>research</string>
+        <key>rebiulding</key>
+        <string>rebuilding</string>
+        <key>rebllions</key>
+        <string>rebellions</string>
+        <key>rebounce</key>
+        <string>rebound</string>
+        <key>reccomend</key>
+        <string>recommend</string>
+        <key>reccomendations</key>
+        <string>recommendations</string>
+        <key>reccomended</key>
+        <string>recommended</string>
+        <key>reccomending</key>
+        <string>recommending</string>
+        <key>reccommend</key>
+        <string>recommend</string>
+        <key>reccommended</key>
+        <string>recommended</string>
+        <key>reccommending</key>
+        <string>recommending</string>
+        <key>reccuring</key>
+        <string>recurring</string>
+        <key>receeded</key>
+        <string>receded</string>
+        <key>receeding</key>
+        <string>receding</string>
+        <key>receivedfrom</key>
+        <string>received from</string>
+        <key>recepient</key>
+        <string>recipient</string>
+        <key>recepients</key>
+        <string>recipients</string>
+        <key>receving</key>
+        <string>receiving</string>
+        <key>rechargable</key>
+        <string>rechargeable</string>
+        <key>reched</key>
+        <string>reached</string>
+        <key>recide</key>
+        <string>reside</string>
+        <key>recided</key>
+        <string>resided</string>
+        <key>recident</key>
+        <string>resident</string>
+        <key>recidents</key>
+        <string>residents</string>
+        <key>reciding</key>
+        <string>residing</string>
+        <key>reciepents</key>
+        <string>recipients</string>
+        <key>reciept</key>
+        <string>receipt</string>
+        <key>recieve</key>
+        <string>receive</string>
+        <key>recieved</key>
+        <string>received</string>
+        <key>reciever</key>
+        <string>receiver</string>
+        <key>recievers</key>
+        <string>receivers</string>
+        <key>recieves</key>
+        <string>receives</string>
+        <key>recieving</key>
+        <string>receiving</string>
+        <key>recipiant</key>
+        <string>recipient</string>
+        <key>recipiants</key>
+        <string>recipients</string>
+        <key>recived</key>
+        <string>received</string>
+        <key>recivership</key>
+        <string>receivership</string>
+        <key>recogise</key>
+        <string>recognise</string>
+        <key>recogize</key>
+        <string>recognize</string>
+        <key>recomend</key>
+        <string>recommend</string>
+        <key>recomended</key>
+        <string>recommended</string>
+        <key>recomending</key>
+        <string>recommending</string>
+        <key>recomends</key>
+        <string>recommends</string>
+        <key>recommedations</key>
+        <string>recommendations</string>
+        <key>reconaissance</key>
+        <string>reconnaissance</string>
+        <key>reconcilation</key>
+        <string>reconciliation</string>
+        <key>reconized</key>
+        <string>recognized</string>
+        <key>reconnaisance</key>
+        <string>reconnaissance</string>
+        <key>reconnaissence</key>
+        <string>reconnaissance</string>
+        <key>recontructed</key>
+        <string>reconstructed</string>
+        <key>recordproducer</key>
+        <string>record producer</string>
+        <key>recquired</key>
+        <string>required</string>
+        <key>recrational</key>
+        <string>recreational</string>
+        <key>recrod</key>
+        <string>record</string>
+        <key>recuiting</key>
+        <string>recruiting</string>
+        <key>recuring</key>
+        <string>recurring</string>
+        <key>recurrance</key>
+        <string>recurrence</string>
+        <key>rediculous</key>
+        <string>ridiculous</string>
+        <key>reedeming</key>
+        <string>redeeming</string>
+        <key>reenforced</key>
+        <string>reinforced</string>
+        <key>refect</key>
+        <string>reflect</string>
+        <key>refedendum</key>
+        <string>referendum</string>
+        <key>referal</key>
+        <string>referral</string>
+        <key>referece</key>
+        <string>reference</string>
+        <key>refereces</key>
+        <string>references</string>
+        <key>refered</key>
+        <string>referred</string>
+        <key>referemce</key>
+        <string>reference</string>
+        <key>referemces</key>
+        <string>references</string>
+        <key>referencs</key>
+        <string>references</string>
+        <key>referenece</key>
+        <string>reference</string>
+        <key>refereneced</key>
+        <string>referenced</string>
+        <key>refereneces</key>
+        <string>references</string>
+        <key>referiang</key>
+        <string>referring</string>
+        <key>refering</key>
+        <string>referring</string>
+        <key>refernce</key>
+        <string>references</string>
+        <key>refernces</key>
+        <string>references</string>
+        <key>referrence</key>
+        <string>reference</string>
+        <key>referrences</key>
+        <string>references</string>
+        <key>referrs</key>
+        <string>refers</string>
+        <key>reffered</key>
+        <string>referred</string>
+        <key>refference</key>
+        <string>reference</string>
+        <key>reffering</key>
+        <string>referring</string>
+        <key>refrence</key>
+        <string>reference</string>
+        <key>refrences</key>
+        <string>references</string>
+        <key>refrers</key>
+        <string>refers</string>
+        <key>refridgeration</key>
+        <string>refrigeration</string>
+        <key>refridgerator</key>
+        <string>refrigerator</string>
+        <key>refromist</key>
+        <string>reformist</string>
+        <key>refusla</key>
+        <string>refusal</string>
+        <key>regardes</key>
+        <string>regards</string>
+        <key>regluar</key>
+        <string>regular</string>
+        <key>reguarly</key>
+        <string>regularly</string>
+        <key>regulaion</key>
+        <string>regulation</string>
+        <key>regulaotrs</key>
+        <string>regulators</string>
+        <key>regularily</key>
+        <string>regularly</string>
+        <key>rehersal</key>
+        <string>rehearsal</string>
+        <key>reicarnation</key>
+        <string>reincarnation</string>
+        <key>reigining</key>
+        <string>reigning</string>
+        <key>reknown</key>
+        <string>renown</string>
+        <key>reknowned</key>
+        <string>renowned</string>
+        <key>rela</key>
+        <string>real</string>
+        <key>relaly</key>
+        <string>really</string>
+        <key>relatiopnship</key>
+        <string>relationship</string>
+        <key>relativly</key>
+        <string>relatively</string>
+        <key>relected</key>
+        <string>reelected</string>
+        <key>releive</key>
+        <string>relieve</string>
+        <key>releived</key>
+        <string>relieved</string>
+        <key>releiver</key>
+        <string>reliever</string>
+        <key>releses</key>
+        <string>releases</string>
+        <key>relevence</key>
+        <string>relevance</string>
+        <key>relevent</key>
+        <string>relevant</string>
+        <key>reliablity</key>
+        <string>reliability</string>
+        <key>relient</key>
+        <string>reliant</string>
+        <key>religeous</key>
+        <string>religious</string>
+        <key>religous</key>
+        <string>religious</string>
+        <key>religously</key>
+        <string>religiously</string>
+        <key>relinqushment</key>
+        <string>relinquishment</string>
+        <key>relitavely</key>
+        <string>relatively</string>
+        <key>relized</key>
+        <string>realized</string>
+        <key>relpacement</key>
+        <string>replacement</string>
+        <key>remaing</key>
+        <string>remaining</string>
+        <key>remeber</key>
+        <string>remember</string>
+        <key>rememberable</key>
+        <string>memorable</string>
+        <key>rememberance</key>
+        <string>remembrance</string>
+        <key>remembrence</key>
+        <string>remembrance</string>
+        <key>remenant</key>
+        <string>remnant</string>
+        <key>remenicent</key>
+        <string>reminiscent</string>
+        <key>reminent</key>
+        <string>remnant</string>
+        <key>reminescent</key>
+        <string>reminiscent</string>
+        <key>reminscent</key>
+        <string>reminiscent</string>
+        <key>reminsicent</key>
+        <string>reminiscent</string>
+        <key>rendevous</key>
+        <string>rendezvous</string>
+        <key>rendezous</key>
+        <string>rendezvous</string>
+        <key>renedered</key>
+        <string>rende</string>
+        <key>renewl</key>
+        <string>renewal</string>
+        <key>rennovate</key>
+        <string>renovate</string>
+        <key>rennovated</key>
+        <string>renovated</string>
+        <key>rennovating</key>
+        <string>renovating</string>
+        <key>rennovation</key>
+        <string>renovation</string>
+        <key>rentors</key>
+        <string>renters</string>
+        <key>reoccurrence</key>
+        <string>recurrence</string>
+        <key>reorganision</key>
+        <string>reorganisation</string>
+        <key>repatition</key>
+        <string>repetition</string>
+        <key>repectively</key>
+        <string>respectively</string>
+        <key>repeition</key>
+        <string>repetition</string>
+        <key>repentence</key>
+        <string>repentance</string>
+        <key>repentent</key>
+        <string>repentant</string>
+        <key>repeteadly</key>
+        <string>repeatedly</string>
+        <key>repetion</key>
+        <string>repetition</string>
+        <key>repid</key>
+        <string>rapid</string>
+        <key>reponse</key>
+        <string>response</string>
+        <key>reponsible</key>
+        <string>responsible</string>
+        <key>reportadly</key>
+        <string>reportedly</string>
+        <key>represantative</key>
+        <string>representative</string>
+        <key>representive</key>
+        <string>representative</string>
+        <key>representives</key>
+        <string>representatives</string>
+        <key>reproducable</key>
+        <string>reproducible</string>
+        <key>reprtoire</key>
+        <string>repertoire</string>
+        <key>repsectively</key>
+        <string>respectively</string>
+        <key>reptition</key>
+        <string>repetition</string>
+        <key>requirment</key>
+        <string>requirement</string>
+        <key>requred</key>
+        <string>required</string>
+        <key>resaurant</key>
+        <string>restaurant</string>
+        <key>resembelance</key>
+        <string>resemblance</string>
+        <key>resembes</key>
+        <string>resembles</string>
+        <key>resemblence</key>
+        <string>resemblance</string>
+        <key>resevoir</key>
+        <string>reservoir</string>
+        <key>residental</key>
+        <string>residential</string>
+        <key>resignement</key>
+        <string>resignment</string>
+        <key>resistable</key>
+        <string>resistible</string>
+        <key>resistence</key>
+        <string>resistance</string>
+        <key>resistent</key>
+        <string>resistant</string>
+        <key>respectivly</key>
+        <string>respectively</string>
+        <key>responce</key>
+        <string>response</string>
+        <key>responibilities</key>
+        <string>responsibilities</string>
+        <key>responisble</key>
+        <string>responsible</string>
+        <key>responnsibilty</key>
+        <string>responsibility</string>
+        <key>responsability</key>
+        <string>responsibility</string>
+        <key>responsibile</key>
+        <string>responsible</string>
+        <key>responsibilites</key>
+        <string>responsibilities</string>
+        <key>responsiblities</key>
+        <string>responsibilities</string>
+        <key>responsiblity</key>
+        <string>responsibility</string>
+        <key>ressemblance</key>
+        <string>resemblance</string>
+        <key>ressemble</key>
+        <string>resemble</string>
+        <key>ressembled</key>
+        <string>resembled</string>
+        <key>ressemblence</key>
+        <string>resemblance</string>
+        <key>ressembling</key>
+        <string>resembling</string>
+        <key>resssurecting</key>
+        <string>resurrecting</string>
+        <key>ressurect</key>
+        <string>resurrect</string>
+        <key>ressurected</key>
+        <string>resurrected</string>
+        <key>ressurection</key>
+        <string>resurrection</string>
+        <key>ressurrection</key>
+        <string>resurrection</string>
+        <key>restarant</key>
+        <string>restaurant</string>
+        <key>restarants</key>
+        <string>restaurants</string>
+        <key>restaraunt</key>
+        <string>restaurant</string>
+        <key>restaraunteur</key>
+        <string>restaurateur</string>
+        <key>restaraunteurs</key>
+        <string>restaurateurs</string>
+        <key>restaraunts</key>
+        <string>restaurants</string>
+        <key>restauranteurs</key>
+        <string>restaurateurs</string>
+        <key>restauration</key>
+        <string>restoration</string>
+        <key>restauraunt</key>
+        <string>restaurant</string>
+        <key>resteraunt</key>
+        <string>restaurant</string>
+        <key>resteraunts</key>
+        <string>restaurants</string>
+        <key>resticted</key>
+        <string>restricted</string>
+        <key>restraunt</key>
+        <string>restraint</string>
+        <key>resturant</key>
+        <string>restaurant</string>
+        <key>resturants</key>
+        <string>restaurants</string>
+        <key>resturaunt</key>
+        <string>restaurant</string>
+        <key>resturaunts</key>
+        <string>restaurants</string>
+        <key>resurecting</key>
+        <string>resurrecting</string>
+        <key>retalitated</key>
+        <string>retaliated</string>
+        <key>retalitation</key>
+        <string>retaliation</string>
+        <key>retreive</key>
+        <string>retrieve</string>
+        <key>returnd</key>
+        <string>returned</string>
+        <key>revaluated</key>
+        <string>reevaluated</string>
+        <key>reveiw</key>
+        <string>review</string>
+        <key>reveral</key>
+        <string>reversal</string>
+        <key>reversable</key>
+        <string>reversible</string>
+        <key>revolutionar</key>
+        <string>revolutionary</string>
+        <key>rewitten</key>
+        <string>rewritten</string>
+        <key>rewriet</key>
+        <string>rewrite</string>
+        <key>rference</key>
+        <string>reference</string>
+        <key>rferences</key>
+        <string>references</string>
+        <key>rhymme</key>
+        <string>rhyme</string>
+        <key>rhythem</key>
+        <string>rhythm</string>
+        <key>rhythim</key>
+        <string>rhythm</string>
+        <key>rhytmic</key>
+        <string>rhythmic</string>
+        <key>rigourous</key>
+        <string>rigorous</string>
+        <key>rininging</key>
+        <string>ringing</string>
+        <key>rised</key>
+        <string>rose</string>
+        <key>rococco</key>
+        <string>rococo</string>
+        <key>rocord</key>
+        <string>record</string>
+        <key>roomate</key>
+        <string>roommate</string>
+        <key>rougly</key>
+        <string>roughly</string>
+        <key>rucuperate</key>
+        <string>recuperate</string>
+        <key>rudimentatry</key>
+        <string>rudimentary</string>
+        <key>rulle</key>
+        <string>rule</string>
+        <key>runing</key>
+        <string>running</string>
+        <key>runnung</key>
+        <string>running</string>
+        <key>russina</key>
+        <string>Russian</string>
+        <key>rwite</key>
+        <string>write</string>
+        <key>rythem</key>
+        <string>rhythm</string>
+        <key>rythim</key>
+        <string>rhythm</string>
+        <key>rythm</key>
+        <string>rhythm</string>
+        <key>rythmic</key>
+        <string>rhythmic</string>
+        <key>rythyms</key>
+        <string>rhythms</string>
+        <key>sacrafice</key>
+        <string>sacrifice</string>
+        <key>sacreligious</key>
+        <string>sacrilegious</string>
+        <key>sacrifical</key>
+        <string>sacrificial</string>
+        <key>saftey</key>
+        <string>safety</string>
+        <key>safty</key>
+        <string>safety</string>
+        <key>salery</key>
+        <string>salary</string>
+        <key>sanctionning</key>
+        <string>sanctioning</string>
+        <key>sandwhich</key>
+        <string>sandwich</string>
+        <key>santioned</key>
+        <string>sanctioned</string>
+        <key>sargant</key>
+        <string>sergeant</string>
+        <key>sargeant</key>
+        <string>sergeant</string>
+        <key>satelite</key>
+        <string>satellite</string>
+        <key>satelites</key>
+        <string>satellites</string>
+        <key>satisfactority</key>
+        <string>satisfactorily</string>
+        <key>satric</key>
+        <string>satiric</string>
+        <key>satrical</key>
+        <string>satirical</string>
+        <key>satrically</key>
+        <string>satirically</string>
+        <key>sattelite</key>
+        <string>satellite</string>
+        <key>sattelites</key>
+        <string>satellites</string>
+        <key>saught</key>
+        <string>sought</string>
+        <key>saveing</key>
+        <string>saving</string>
+        <key>saxaphone</key>
+        <string>saxophone</string>
+        <key>scaleable</key>
+        <string>scalable</string>
+        <key>scandanavia</key>
+        <string>Scandinavia</string>
+        <key>scaricity</key>
+        <string>scarcity</string>
+        <key>scavanged</key>
+        <string>scavenged</string>
+        <key>schedual</key>
+        <string>schedule</string>
+        <key>scholarhip</key>
+        <string>scholarship</string>
+        <key>scholarstic</key>
+        <string>scholastic</string>
+        <key>scientfic</key>
+        <string>scientific</string>
+        <key>scientifc</key>
+        <string>scientific</string>
+        <key>scientis</key>
+        <string>scientist</string>
+        <key>scince</key>
+        <string>science</string>
+        <key>scinece</key>
+        <string>science</string>
+        <key>scirpt</key>
+        <string>script</string>
+        <key>scoll</key>
+        <string>scroll</string>
+        <key>screenwrighter</key>
+        <string>screenwriter</string>
+        <key>scrutinity</key>
+        <string>scrutiny</string>
+        <key>scuptures</key>
+        <string>sculptures</string>
+        <key>seach</key>
+        <string>search</string>
+        <key>seached</key>
+        <string>searched</string>
+        <key>seaches</key>
+        <string>searches</string>
+        <key>secratary</key>
+        <string>secretary</string>
+        <key>secretery</key>
+        <string>secretary</string>
+        <key>sedereal</key>
+        <string>sidereal</string>
+        <key>seeked</key>
+        <string>sought</string>
+        <key>segementation</key>
+        <string>segmentation</string>
+        <key>seguoys</key>
+        <string>segues</string>
+        <key>seige</key>
+        <string>siege</string>
+        <key>seing</key>
+        <string>seeing</string>
+        <key>seinor</key>
+        <string>senior</string>
+        <key>seldomly</key>
+        <string>seldom</string>
+        <key>senarios</key>
+        <string>scenarios</string>
+        <key>senstive</key>
+        <string>sensitive</string>
+        <key>sensure</key>
+        <string>censure</string>
+        <key>seperate</key>
+        <string>separate</string>
+        <key>seperated</key>
+        <string>separated</string>
+        <key>seperately</key>
+        <string>separately</string>
+        <key>seperates</key>
+        <string>separates</string>
+        <key>seperating</key>
+        <string>separating</string>
+        <key>seperation</key>
+        <string>separation</string>
+        <key>seperatism</key>
+        <string>separatism</string>
+        <key>seperatist</key>
+        <string>separatist</string>
+        <key>sepina</key>
+        <string>subpoena</string>
+        <key>sergent</key>
+        <string>sergeant</string>
+        <key>settelement</key>
+        <string>settlement</string>
+        <key>settlment</key>
+        <string>settlement</string>
+        <key>severeal</key>
+        <string>several</string>
+        <key>severley</key>
+        <string>severely</string>
+        <key>severly</key>
+        <string>severely</string>
+        <key>sevice</key>
+        <string>service</string>
+        <key>shadasloo</key>
+        <string>shadaloo</string>
+        <key>shaddow</key>
+        <string>shadow</string>
+        <key>shadoloo</key>
+        <string>shadaloo</string>
+        <key>shamen</key>
+        <string>shaman</string>
+        <key>sheat</key>
+        <string>sheath</string>
+        <key>sheild</key>
+        <string>shield</string>
+        <key>sherif</key>
+        <string>sheriff</string>
+        <key>shineing</key>
+        <string>shining</string>
+        <key>shiped</key>
+        <string>shipped</string>
+        <key>shiping</key>
+        <string>shipping</string>
+        <key>shopkeeepers</key>
+        <string>shopkeepers</string>
+        <key>shorly</key>
+        <string>shortly</string>
+        <key>shortwhile</key>
+        <string>short while</string>
+        <key>shoudl</key>
+        <string>should</string>
+        <key>shoudln</key>
+        <string>shouldn&apos;t</string>
+        <key>shouldnt</key>
+        <string>shouldn&apos;t</string>
+        <key>shreak</key>
+        <string>shriek</string>
+        <key>shrinked</key>
+        <string>shrunk</string>
+        <key>sicne</key>
+        <string>since</string>
+        <key>sideral</key>
+        <string>sidereal</string>
+        <key>siezure</key>
+        <string>seizure</string>
+        <key>siezures</key>
+        <string>seizures</string>
+        <key>siginificant</key>
+        <string>significant</string>
+        <key>signficant</key>
+        <string>significant</string>
+        <key>signficiant</key>
+        <string>significant</string>
+        <key>signfies</key>
+        <string>signifies</string>
+        <key>signifantly</key>
+        <string>significantly</string>
+        <key>significently</key>
+        <string>significantly</string>
+        <key>signifigant</key>
+        <string>significant</string>
+        <key>signifigantly</key>
+        <string>significantly</string>
+        <key>signitories</key>
+        <string>signatories</string>
+        <key>signitory</key>
+        <string>signatory</string>
+        <key>similarily</key>
+        <string>similarly</string>
+        <key>similiar</key>
+        <string>similar</string>
+        <key>similiarity</key>
+        <string>similarity</string>
+        <key>similiarly</key>
+        <string>similarly</string>
+        <key>simmilar</key>
+        <string>similar</string>
+        <key>simpley</key>
+        <string>simply</string>
+        <key>simplier</key>
+        <string>simpler</string>
+        <key>simultanous</key>
+        <string>simultaneous</string>
+        <key>simultanously</key>
+        <string>simultaneously</string>
+        <key>sincerley</key>
+        <string>sincerely</string>
+        <key>singsog</key>
+        <string>singsong</string>
+        <key>sinse</key>
+        <string>since</string>
+        <key>skateing</key>
+        <string>skating</string>
+        <key>slaugterhouses</key>
+        <string>slaughterhouses</string>
+        <key>slighly</key>
+        <string>slightly</string>
+        <key>slowy</key>
+        <string>slowly</string>
+        <key>smae</key>
+        <string>same</string>
+        <key>smealting</key>
+        <string>smelting</string>
+        <key>smoe</key>
+        <string>some</string>
+        <key>sneeks</key>
+        <string>sneaks</string>
+        <key>snese</key>
+        <string>sneeze</string>
+        <key>socalism</key>
+        <string>socialism</string>
+        <key>socities</key>
+        <string>societies</string>
+        <key>soem</key>
+        <string>some</string>
+        <key>sofware</key>
+        <string>software</string>
+        <key>sohw</key>
+        <string>show</string>
+        <key>soilders</key>
+        <string>soldiers</string>
+        <key>solatary</key>
+        <string>solitary</string>
+        <key>soley</key>
+        <string>solely</string>
+        <key>soliders</key>
+        <string>soldiers</string>
+        <key>soliliquy</key>
+        <string>soliloquy</string>
+        <key>soluable</key>
+        <string>soluble</string>
+        <key>somene</key>
+        <string>someone</string>
+        <key>somtimes</key>
+        <string>sometimes</string>
+        <key>somwhere</key>
+        <string>somewhere</string>
+        <key>sophicated</key>
+        <string>sophisticated</string>
+        <key>sophmore</key>
+        <string>sophomore</string>
+        <key>sorceror</key>
+        <string>sorcerer</string>
+        <key>sorrounding</key>
+        <string>surrounding</string>
+        <key>sotry</key>
+        <string>story</string>
+        <key>sotyr</key>
+        <string>story</string>
+        <key>soudn</key>
+        <string>sound</string>
+        <key>soudns</key>
+        <string>sounds</string>
+        <key>sould</key>
+        <string>could</string>
+        <key>sountrack</key>
+        <string>soundtrack</string>
+        <key>sourth</key>
+        <string>south</string>
+        <key>sourthern</key>
+        <string>southern</string>
+        <key>souvenier</key>
+        <string>souvenir</string>
+        <key>souveniers</key>
+        <string>souvenirs</string>
+        <key>soveits</key>
+        <string>soviets</string>
+        <key>sovereignity</key>
+        <string>sovereignty</string>
+        <key>soverign</key>
+        <string>sovereign</string>
+        <key>soverignity</key>
+        <string>sovereignty</string>
+        <key>soverignty</key>
+        <string>sovereignty</string>
+        <key>spainish</key>
+        <string>Spanish</string>
+        <key>speach</key>
+        <string>speech</string>
+        <key>specfic</key>
+        <string>specific</string>
+        <key>speciallized</key>
+        <string>specialized</string>
+        <key>specifiying</key>
+        <string>specifying</string>
+        <key>speciman</key>
+        <string>specimen</string>
+        <key>spectauclar</key>
+        <string>spectacular</string>
+        <key>spectaulars</key>
+        <string>spectaculars</string>
+        <key>spectum</key>
+        <string>spectrum</string>
+        <key>speices</key>
+        <string>species</string>
+        <key>spendour</key>
+        <string>splendour</string>
+        <key>spermatozoan</key>
+        <string>spermatozoon</string>
+        <key>spoace</key>
+        <string>space</string>
+        <key>sponser</key>
+        <string>sponsor</string>
+        <key>sponsered</key>
+        <string>sponsored</string>
+        <key>spontanous</key>
+        <string>spontaneous</string>
+        <key>sponzored</key>
+        <string>sponsored</string>
+        <key>spoonfulls</key>
+        <string>spoonfuls</string>
+        <key>sppeches</key>
+        <string>speeches</string>
+        <key>spreaded</key>
+        <string>spread</string>
+        <key>sprech</key>
+        <string>speech</string>
+        <key>spred</key>
+        <string>spread</string>
+        <key>spriritual</key>
+        <string>spiritual</string>
+        <key>spritual</key>
+        <string>spiritual</string>
+        <key>sqaure</key>
+        <string>square</string>
+        <key>stablility</key>
+        <string>stability</string>
+        <key>stainlees</key>
+        <string>stainless</string>
+        <key>staion</key>
+        <string>station</string>
+        <key>standars</key>
+        <string>standards</string>
+        <key>stange</key>
+        <string>strange</string>
+        <key>startegic</key>
+        <string>strategic</string>
+        <key>startegies</key>
+        <string>strategies</string>
+        <key>startegy</key>
+        <string>strategy</string>
+        <key>stateman</key>
+        <string>statesman</string>
+        <key>statememts</key>
+        <string>statements</string>
+        <key>statment</key>
+        <string>statement</string>
+        <key>steriods</key>
+        <string>steroids</string>
+        <key>sterotypes</key>
+        <string>stereotypes</string>
+        <key>stilus</key>
+        <string>stylus</string>
+        <key>stingent</key>
+        <string>stringent</string>
+        <key>stiring</key>
+        <string>stirring</string>
+        <key>stirrs</key>
+        <string>stirs</string>
+        <key>stlye</key>
+        <string>style</string>
+        <key>stomache</key>
+        <string>stomach</string>
+        <key>stong</key>
+        <string>strong</string>
+        <key>stopry</key>
+        <string>story</string>
+        <key>storeis</key>
+        <string>stories</string>
+        <key>storise</key>
+        <string>stories</string>
+        <key>stornegst</key>
+        <string>strongest</string>
+        <key>stoyr</key>
+        <string>story</string>
+        <key>stpo</key>
+        <string>stop</string>
+        <key>stradegies</key>
+        <string>strategies</string>
+        <key>stradegy</key>
+        <string>strategy</string>
+        <key>strat</key>
+        <string>start</string>
+        <key>stratagically</key>
+        <string>strategically</string>
+        <key>streemlining</key>
+        <string>streamlining</string>
+        <key>stregth</key>
+        <string>strength</string>
+        <key>strenghen</key>
+        <string>strengthen</string>
+        <key>strenghened</key>
+        <string>strengthened</string>
+        <key>strenghening</key>
+        <string>strengthening</string>
+        <key>strenght</key>
+        <string>strength</string>
+        <key>strenghten</key>
+        <string>strengthen</string>
+        <key>strenghtened</key>
+        <string>strengthened</string>
+        <key>strenghtening</key>
+        <string>strengthening</string>
+        <key>strengtened</key>
+        <string>strengthened</string>
+        <key>strenous</key>
+        <string>strenuous</string>
+        <key>strictist</key>
+        <string>strictest</string>
+        <key>strikely</key>
+        <string>strikingly</string>
+        <key>strnad</key>
+        <string>strand</string>
+        <key>stroy</key>
+        <string>story</string>
+        <key>structual</key>
+        <string>structural</string>
+        <key>stubborness</key>
+        <string>stubbornness</string>
+        <key>stucture</key>
+        <string>structure</string>
+        <key>stuctured</key>
+        <string>structured</string>
+        <key>studdy</key>
+        <string>study</string>
+        <key>studing</key>
+        <string>studying</string>
+        <key>stuggling</key>
+        <string>struggling</string>
+        <key>sturcture</key>
+        <string>structure</string>
+        <key>subcatagories</key>
+        <string>subcategories</string>
+        <key>subcatagory</key>
+        <string>subcategory</string>
+        <key>subconsiously</key>
+        <string>subconsciously</string>
+        <key>subjudgation</key>
+        <string>subjugation</string>
+        <key>submachne</key>
+        <string>submachine</string>
+        <key>subpecies</key>
+        <string>subspecies</string>
+        <key>subsidary</key>
+        <string>subsidiary</string>
+        <key>subsiduary</key>
+        <string>subsidiary</string>
+        <key>subsquent</key>
+        <string>subsequent</string>
+        <key>subsquently</key>
+        <string>subsequently</string>
+        <key>substace</key>
+        <string>substance</string>
+        <key>substancial</key>
+        <string>substantial</string>
+        <key>substatial</key>
+        <string>substantial</string>
+        <key>substituded</key>
+        <string>substituted</string>
+        <key>substract</key>
+        <string>subtract</string>
+        <key>substracted</key>
+        <string>subtracted</string>
+        <key>substracting</key>
+        <string>subtracting</string>
+        <key>substraction</key>
+        <string>subtraction</string>
+        <key>substracts</key>
+        <string>subtracts</string>
+        <key>subtances</key>
+        <string>substances</string>
+        <key>subterranian</key>
+        <string>subterranean</string>
+        <key>suburburban</key>
+        <string>suburban</string>
+        <key>succceeded</key>
+        <string>succeeded</string>
+        <key>succcesses</key>
+        <string>successes</string>
+        <key>succedded</key>
+        <string>succeeded</string>
+        <key>succeded</key>
+        <string>succeeded</string>
+        <key>succeds</key>
+        <string>succeeds</string>
+        <key>succesful</key>
+        <string>successful</string>
+        <key>succesfully</key>
+        <string>successfully</string>
+        <key>succesfuly</key>
+        <string>successfully</string>
+        <key>succesion</key>
+        <string>succession</string>
+        <key>succesive</key>
+        <string>successive</string>
+        <key>successfull</key>
+        <string>successful</string>
+        <key>successully</key>
+        <string>successfully</string>
+        <key>succsess</key>
+        <string>success</string>
+        <key>succsessfull</key>
+        <string>successful</string>
+        <key>suceed</key>
+        <string>succeed</string>
+        <key>suceeded</key>
+        <string>succeeded</string>
+        <key>suceeding</key>
+        <string>succeeding</string>
+        <key>suceeds</key>
+        <string>succeeds</string>
+        <key>sucesful</key>
+        <string>successful</string>
+        <key>sucesfully</key>
+        <string>successfully</string>
+        <key>sucesfuly</key>
+        <string>successfully</string>
+        <key>sucesion</key>
+        <string>succession</string>
+        <key>sucess</key>
+        <string>success</string>
+        <key>sucesses</key>
+        <string>successes</string>
+        <key>sucessful</key>
+        <string>successful</string>
+        <key>sucessfull</key>
+        <string>successful</string>
+        <key>sucessfully</key>
+        <string>successfully</string>
+        <key>sucessfuly</key>
+        <string>successfully</string>
+        <key>sucession</key>
+        <string>succession</string>
+        <key>sucessive</key>
+        <string>successive</string>
+        <key>sucessor</key>
+        <string>successor</string>
+        <key>sucessot</key>
+        <string>successor</string>
+        <key>sucide</key>
+        <string>suicide</string>
+        <key>sucidial</key>
+        <string>suicidal</string>
+        <key>sufferage</key>
+        <string>suffrage</string>
+        <key>sufferred</key>
+        <string>suffered</string>
+        <key>sufferring</key>
+        <string>suffering</string>
+        <key>sufficent</key>
+        <string>sufficient</string>
+        <key>sufficently</key>
+        <string>sufficiently</string>
+        <key>sumary</key>
+        <string>summary</string>
+        <key>sunglases</key>
+        <string>sunglasses</string>
+        <key>suop</key>
+        <string>soup</string>
+        <key>superceeded</key>
+        <string>superseded</string>
+        <key>superintendant</key>
+        <string>superintendent</string>
+        <key>suphisticated</key>
+        <string>sophisticated</string>
+        <key>suplimented</key>
+        <string>supplemented</string>
+        <key>supose</key>
+        <string>suppose</string>
+        <key>suposed</key>
+        <string>supposed</string>
+        <key>suposedly</key>
+        <string>supposedly</string>
+        <key>suposes</key>
+        <string>supposes</string>
+        <key>suposing</key>
+        <string>supposing</string>
+        <key>supplamented</key>
+        <string>supplemented</string>
+        <key>suppliementing</key>
+        <string>supplementing</string>
+        <key>suppoed</key>
+        <string>supposed</string>
+        <key>supposingly</key>
+        <string>supposedly</string>
+        <key>suppy</key>
+        <string>supply</string>
+        <key>supress</key>
+        <string>suppress</string>
+        <key>supressed</key>
+        <string>suppressed</string>
+        <key>supresses</key>
+        <string>suppresses</string>
+        <key>supressing</key>
+        <string>suppressing</string>
+        <key>suprise</key>
+        <string>surprise</string>
+        <key>suprised</key>
+        <string>surprised</string>
+        <key>suprising</key>
+        <string>surprising</string>
+        <key>suprisingly</key>
+        <string>surprisingly</string>
+        <key>suprize</key>
+        <string>surprise</string>
+        <key>suprized</key>
+        <string>surprised</string>
+        <key>suprizing</key>
+        <string>surprising</string>
+        <key>suprizingly</key>
+        <string>surprisingly</string>
+        <key>surfce</key>
+        <string>surface</string>
+        <key>surley</key>
+        <string>surely</string>
+        <key>suround</key>
+        <string>surround</string>
+        <key>surounded</key>
+        <string>surrounded</string>
+        <key>surounding</key>
+        <string>surrounding</string>
+        <key>suroundings</key>
+        <string>surroundings</string>
+        <key>surounds</key>
+        <string>surrounds</string>
+        <key>surplanted</key>
+        <string>supplanted</string>
+        <key>surpress</key>
+        <string>suppress</string>
+        <key>surpressed</key>
+        <string>suppressed</string>
+        <key>surprize</key>
+        <string>surprise</string>
+        <key>surprized</key>
+        <string>surprised</string>
+        <key>surprizing</key>
+        <string>surprising</string>
+        <key>surprizingly</key>
+        <string>surprisingly</string>
+        <key>surrended</key>
+        <string>surrendered</string>
+        <key>surrepetitious</key>
+        <string>surreptitious</string>
+        <key>surrepetitiously</key>
+        <string>surreptitiously</string>
+        <key>surreptious</key>
+        <string>surreptitious</string>
+        <key>surreptiously</key>
+        <string>surreptitiously</string>
+        <key>surronded</key>
+        <string>surrounded</string>
+        <key>surrouded</key>
+        <string>surrounded</string>
+        <key>surrouding</key>
+        <string>surrounding</string>
+        <key>surrundering</key>
+        <string>surrendering</string>
+        <key>surveilence</key>
+        <string>surveillance</string>
+        <key>surveill</key>
+        <string>surveil</string>
+        <key>surveyer</key>
+        <string>surveyor</string>
+        <key>surviver</key>
+        <string>survivor</string>
+        <key>survivers</key>
+        <string>survivors</string>
+        <key>survivied</key>
+        <string>survived</string>
+        <key>suseptable</key>
+        <string>susceptible</string>
+        <key>suseptible</key>
+        <string>susceptible</string>
+        <key>suspention</key>
+        <string>suspension</string>
+        <key>swaer</key>
+        <string>swear</string>
+        <key>swaers</key>
+        <string>swears</string>
+        <key>swepth</key>
+        <string>swept</string>
+        <key>swiming</key>
+        <string>swimming</string>
+        <key>syas</key>
+        <string>says</string>
+        <key>symetrical</key>
+        <string>symmetrical</string>
+        <key>symetrically</key>
+        <string>symmetrically</string>
+        <key>symetry</key>
+        <string>symmetry</string>
+        <key>symettric</key>
+        <string>symmetric</string>
+        <key>symmetral</key>
+        <string>symmetric</string>
+        <key>symmetricaly</key>
+        <string>symmetrically</string>
+        <key>synagouge</key>
+        <string>synagogue</string>
+        <key>syncronization</key>
+        <string>synchronization</string>
+        <key>synonomous</key>
+        <string>synonymous</string>
+        <key>synonymns</key>
+        <string>synonyms</string>
+        <key>synphony</key>
+        <string>symphony</string>
+        <key>syphyllis</key>
+        <string>syphilis</string>
+        <key>sypmtoms</key>
+        <string>symptoms</string>
+        <key>syrap</key>
+        <string>syrup</string>
+        <key>sysmatically</key>
+        <string>systematically</string>
+        <key>sytem</key>
+        <string>system</string>
+        <key>sytle</key>
+        <string>style</string>
+        <key>tabacco</key>
+        <string>tobacco</string>
+        <key>tahn</key>
+        <string>than</string>
+        <key>taht</key>
+        <string>that</string>
+        <key>talekd</key>
+        <string>talked</string>
+        <key>targetted</key>
+        <string>targeted</string>
+        <key>targetting</key>
+        <string>targeting</string>
+        <key>tast</key>
+        <string>taste</string>
+        <key>tath</key>
+        <string>that</string>
+        <key>tattooes</key>
+        <string>tattoos</string>
+        <key>taxanomic</key>
+        <string>taxonomic</string>
+        <key>taxanomy</key>
+        <string>taxonomy</string>
+        <key>teached</key>
+        <string>taught</string>
+        <key>techician</key>
+        <string>technician</string>
+        <key>techicians</key>
+        <string>technicians</string>
+        <key>techiniques</key>
+        <string>techniques</string>
+        <key>technitian</key>
+        <string>technician</string>
+        <key>technnology</key>
+        <string>technology</string>
+        <key>technolgy</key>
+        <string>technology</string>
+        <key>teh</key>
+        <string>the</string>
+        <key>tehy</key>
+        <string>they</string>
+        <key>telelevision</key>
+        <string>television</string>
+        <key>televsion</key>
+        <string>television</string>
+        <key>telphony</key>
+        <string>telephony</string>
+        <key>temerature</key>
+        <string>temperature</string>
+        <key>tempalte</key>
+        <string>template</string>
+        <key>tempaltes</key>
+        <string>templates</string>
+        <key>temparate</key>
+        <string>temperate</string>
+        <key>temperarily</key>
+        <string>temporarily</string>
+        <key>temperment</key>
+        <string>temperament</string>
+        <key>tempertaure</key>
+        <string>temperature</string>
+        <key>temperture</key>
+        <string>temperature</string>
+        <key>temprary</key>
+        <string>temporary</string>
+        <key>tenacle</key>
+        <string>tentacle</string>
+        <key>tenacles</key>
+        <string>tentacles</string>
+        <key>tendacy</key>
+        <string>tendency</string>
+        <key>tendancies</key>
+        <string>tendencies</string>
+        <key>tendancy</key>
+        <string>tendency</string>
+        <key>tennisplayer</key>
+        <string>tennis player</string>
+        <key>tepmorarily</key>
+        <string>temporarily</string>
+        <key>terrestial</key>
+        <string>terrestrial</string>
+        <key>terriories</key>
+        <string>territories</string>
+        <key>terriory</key>
+        <string>territory</string>
+        <key>territorist</key>
+        <string>terrorist</string>
+        <key>territoy</key>
+        <string>territory</string>
+        <key>terroist</key>
+        <string>terrorist</string>
+        <key>testiclular</key>
+        <string>testicular</string>
+        <key>tghe</key>
+        <string>the</string>
+        <key>thast</key>
+        <string>that&apos;s</string>
+        <key>theather</key>
+        <string>theater</string>
+        <key>theese</key>
+        <string>these</string>
+        <key>theif</key>
+        <string>thief</string>
+        <key>theives</key>
+        <string>thieves</string>
+        <key>themselfs</key>
+        <string>themselves</string>
+        <key>themslves</key>
+        <string>themselves</string>
+        <key>ther</key>
+        <string>there</string>
+        <key>therafter</key>
+        <string>thereafter</string>
+        <key>therby</key>
+        <string>thereby</string>
+        <key>theri</key>
+        <string>their</string>
+        <key>theyre</key>
+        <string>they&apos;re</string>
+        <key>thgat</key>
+        <string>that</string>
+        <key>thge</key>
+        <string>the</string>
+        <key>thier</key>
+        <string>their</string>
+        <key>thign</key>
+        <string>thing</string>
+        <key>thigns</key>
+        <string>things</string>
+        <key>thigsn</key>
+        <string>things</string>
+        <key>thikn</key>
+        <string>think</string>
+        <key>thikning</key>
+        <string>thinking</string>
+        <key>thikns</key>
+        <string>thinks</string>
+        <key>thiunk</key>
+        <string>think</string>
+        <key>thn</key>
+        <string>then</string>
+        <key>thna</key>
+        <string>than</string>
+        <key>thne</key>
+        <string>then</string>
+        <key>thnig</key>
+        <string>thing</string>
+        <key>thnigs</key>
+        <string>things</string>
+        <key>thoughout</key>
+        <string>throughout</string>
+        <key>threatend</key>
+        <string>threatened</string>
+        <key>threatning</key>
+        <string>threatening</string>
+        <key>threee</key>
+        <string>three</string>
+        <key>threshhold</key>
+        <string>threshold</string>
+        <key>thrid</key>
+        <string>third</string>
+        <key>throrough</key>
+        <string>thorough</string>
+        <key>throughly</key>
+        <string>thoroughly</string>
+        <key>throught</key>
+        <string>throat</string>
+        <key>througout</key>
+        <string>throughout</string>
+        <key>thru</key>
+        <string>through</string>
+        <key>thsi</key>
+        <string>this</string>
+        <key>thsoe</key>
+        <string>those</string>
+        <key>thta</key>
+        <string>that</string>
+        <key>thyat</key>
+        <string>that</string>
+        <key>tiem</key>
+        <string>time</string>
+        <key>tihkn</key>
+        <string>think</string>
+        <key>tihs</key>
+        <string>this</string>
+        <key>timne</key>
+        <string>time</string>
+        <key>tiome</key>
+        <string>time</string>
+        <key>tje</key>
+        <string>the</string>
+        <key>tjhe</key>
+        <string>the</string>
+        <key>tjpanishad</key>
+        <string>upanishad</string>
+        <key>tkae</key>
+        <string>take</string>
+        <key>tkaes</key>
+        <string>takes</string>
+        <key>tkaing</key>
+        <string>taking</string>
+        <key>tlaking</key>
+        <string>talking</string>
+        <key>tobbaco</key>
+        <string>tobacco</string>
+        <key>todays</key>
+        <string>today&apos;s</string>
+        <key>todya</key>
+        <string>today</string>
+        <key>toghether</key>
+        <string>together</string>
+        <key>toke</key>
+        <string>took</string>
+        <key>tolerence</key>
+        <string>tolerance</string>
+        <key>tomatos</key>
+        <string>tomatoes</string>
+        <key>tommorow</key>
+        <string>tomorrow</string>
+        <key>tommorrow</key>
+        <string>tomorrow</string>
+        <key>tongiht</key>
+        <string>tonight</string>
+        <key>toriodal</key>
+        <string>toroidal</string>
+        <key>tormenters</key>
+        <string>tormentors</string>
+        <key>tornadoe</key>
+        <string>tornado</string>
+        <key>torpeados</key>
+        <string>torpedoes</string>
+        <key>torpedos</key>
+        <string>torpedoes</string>
+        <key>tothe</key>
+        <string>to the</string>
+        <key>toubles</key>
+        <string>troubles</string>
+        <key>tounge</key>
+        <string>tongue</string>
+        <key>tourch</key>
+        <string>torch</string>
+        <key>towords</key>
+        <string>towards</string>
+        <key>towrad</key>
+        <string>toward</string>
+        <key>tradionally</key>
+        <string>traditionally</string>
+        <key>traditionaly</key>
+        <string>traditionally</string>
+        <key>traditionnal</key>
+        <string>traditional</string>
+        <key>traditition</key>
+        <string>tradition</string>
+        <key>tradtionally</key>
+        <string>traditionally</string>
+        <key>trafficed</key>
+        <string>trafficked</string>
+        <key>trafficing</key>
+        <string>trafficking</string>
+        <key>trafic</key>
+        <string>traffic</string>
+        <key>trancendent</key>
+        <string>transcendent</string>
+        <key>trancending</key>
+        <string>transcending</string>
+        <key>tranform</key>
+        <string>transform</string>
+        <key>tranformed</key>
+        <string>transformed</string>
+        <key>transcendance</key>
+        <string>transcendence</string>
+        <key>transcendant</key>
+        <string>transcendent</string>
+        <key>transcendentational</key>
+        <string>transcendental</string>
+        <key>transcripting</key>
+        <string>transcribing</string>
+        <key>transending</key>
+        <string>transcending</string>
+        <key>transesxuals</key>
+        <string>transsexuals</string>
+        <key>transfered</key>
+        <string>transferred</string>
+        <key>transfering</key>
+        <string>transferring</string>
+        <key>transformaton</key>
+        <string>transformation</string>
+        <key>transistion</key>
+        <string>transition</string>
+        <key>translater</key>
+        <string>translator</string>
+        <key>translaters</key>
+        <string>translators</string>
+        <key>transmissable</key>
+        <string>transmissible</string>
+        <key>transporation</key>
+        <string>transportation</string>
+        <key>tremelo</key>
+        <string>tremolo</string>
+        <key>tremelos</key>
+        <string>tremolos</string>
+        <key>triguered</key>
+        <string>triggered</string>
+        <key>triology</key>
+        <string>trilogy</string>
+        <key>troling</key>
+        <string>trolling</string>
+        <key>troup</key>
+        <string>troupe</string>
+        <key>troups</key>
+        <string>troops</string>
+        <key>truely</key>
+        <string>truly</string>
+        <key>trustworthyness</key>
+        <string>trustworthiness</string>
+        <key>turnk</key>
+        <string>trunk</string>
+        <key>tust</key>
+        <string>trust</string>
+        <key>twelth</key>
+        <string>twelfth</string>
+        <key>twon</key>
+        <string>town</string>
+        <key>twpo</key>
+        <string>two</string>
+        <key>tyhat</key>
+        <string>that</string>
+        <key>tyhe</key>
+        <string>they</string>
+        <key>typcial</key>
+        <string>typical</string>
+        <key>typicaly</key>
+        <string>typically</string>
+        <key>tyranies</key>
+        <string>tyrannies</string>
+        <key>tyrany</key>
+        <string>tyranny</string>
+        <key>tyrranies</key>
+        <string>tyrannies</string>
+        <key>tyrrany</key>
+        <string>tyranny</string>
+        <key>ubiquitious</key>
+        <string>ubiquitous</string>
+        <key>ublisher</key>
+        <string>publisher</string>
+        <key>uise</key>
+        <string>use</string>
+        <key>ultimely</key>
+        <string>ultimately</string>
+        <key>unacompanied</key>
+        <string>unaccompanied</string>
+        <key>unahppy</key>
+        <string>unhappy</string>
+        <key>unanymous</key>
+        <string>unanimous</string>
+        <key>unathorised</key>
+        <string>unauthorised</string>
+        <key>unavailible</key>
+        <string>unavailable</string>
+        <key>unballance</key>
+        <string>unbalance</string>
+        <key>unbeknowst</key>
+        <string>unbeknownst</string>
+        <key>unbeleivable</key>
+        <string>unbelievable</string>
+        <key>uncertainity</key>
+        <string>uncertainty</string>
+        <key>unchallengable</key>
+        <string>unchallengeable</string>
+        <key>unchangable</key>
+        <string>unchangeable</string>
+        <key>uncompetive</key>
+        <string>uncompetitive</string>
+        <key>unconcious</key>
+        <string>unconscious</string>
+        <key>unconciousness</key>
+        <string>unconsciousness</string>
+        <key>unconfortability</key>
+        <string>discomfort</string>
+        <key>uncontitutional</key>
+        <string>unconstitutional</string>
+        <key>unconvential</key>
+        <string>unconventional</string>
+        <key>undecideable</key>
+        <string>undecidable</string>
+        <key>understoon</key>
+        <string>understood</string>
+        <key>undesireable</key>
+        <string>undesirable</string>
+        <key>undetecable</key>
+        <string>undetectable</string>
+        <key>undoubtely</key>
+        <string>undoubtedly</string>
+        <key>undreground</key>
+        <string>underground</string>
+        <key>uneccesary</key>
+        <string>unnecessary</string>
+        <key>unecessary</key>
+        <string>unnecessary</string>
+        <key>unequalities</key>
+        <string>inequalities</string>
+        <key>unforetunately</key>
+        <string>unfortunately</string>
+        <key>unforgetable</key>
+        <string>unforgettable</string>
+        <key>unforgiveable</key>
+        <string>unforgivable</string>
+        <key>unfortunatley</key>
+        <string>unfortunately</string>
+        <key>unfortunatly</key>
+        <string>unfortunately</string>
+        <key>unfourtunately</key>
+        <string>unfortunately</string>
+        <key>unihabited</key>
+        <string>uninhabited</string>
+        <key>unilateraly</key>
+        <string>unilaterally</string>
+        <key>unilatreal</key>
+        <string>unilateral</string>
+        <key>unilatreally</key>
+        <string>unilaterally</string>
+        <key>uninterruped</key>
+        <string>uninterrupted</string>
+        <key>uninterupted</key>
+        <string>uninterrupted</string>
+        <key>univeral</key>
+        <string>universal</string>
+        <key>univeristies</key>
+        <string>universities</string>
+        <key>univeristy</key>
+        <string>university</string>
+        <key>univerity</key>
+        <string>university</string>
+        <key>universtiy</key>
+        <string>university</string>
+        <key>univesities</key>
+        <string>universities</string>
+        <key>univesity</key>
+        <string>university</string>
+        <key>unkown</key>
+        <string>unknown</string>
+        <key>unlikey</key>
+        <string>unlikely</string>
+        <key>unmanouverable</key>
+        <string>unmaneuverable</string>
+        <key>unmistakeably</key>
+        <string>unmistakably</string>
+        <key>unneccesarily</key>
+        <string>unnecessarily</string>
+        <key>unneccesary</key>
+        <string>unnecessary</string>
+        <key>unneccessarily</key>
+        <string>unnecessarily</string>
+        <key>unneccessary</key>
+        <string>unnecessary</string>
+        <key>unnecesarily</key>
+        <string>unnecessarily</string>
+        <key>unnecesary</key>
+        <string>unnecessary</string>
+        <key>unoffical</key>
+        <string>unofficial</string>
+        <key>unoperational</key>
+        <string>nonoperational</string>
+        <key>unoticeable</key>
+        <string>unnoticeable</string>
+        <key>unplease</key>
+        <string>displease</string>
+        <key>unplesant</key>
+        <string>unpleasant</string>
+        <key>unprecendented</key>
+        <string>unprecedented</string>
+        <key>unprecidented</key>
+        <string>unprecedented</string>
+        <key>unrepentent</key>
+        <string>unrepentant</string>
+        <key>unrepetant</key>
+        <string>unrepentant</string>
+        <key>unrepetent</key>
+        <string>unrepentant</string>
+        <key>unsed</key>
+        <string>unused</string>
+        <key>unsubstanciated</key>
+        <string>unsubstantiated</string>
+        <key>unsuccesful</key>
+        <string>unsuccessful</string>
+        <key>unsuccesfully</key>
+        <string>unsuccessfully</string>
+        <key>unsuccessfull</key>
+        <string>unsuccessful</string>
+        <key>unsucesful</key>
+        <string>unsuccessful</string>
+        <key>unsucesfuly</key>
+        <string>unsuccessfully</string>
+        <key>unsucessful</key>
+        <string>unsuccessful</string>
+        <key>unsucessfull</key>
+        <string>unsuccessful</string>
+        <key>unsucessfully</key>
+        <string>unsuccessfully</string>
+        <key>unsuprised</key>
+        <string>unsurprised</string>
+        <key>unsuprising</key>
+        <string>unsurprising</string>
+        <key>unsuprisingly</key>
+        <string>unsurprisingly</string>
+        <key>unsuprized</key>
+        <string>unsurprised</string>
+        <key>unsuprizing</key>
+        <string>unsurprising</string>
+        <key>unsuprizingly</key>
+        <string>unsurprisingly</string>
+        <key>unsurprized</key>
+        <string>unsurprised</string>
+        <key>unsurprizing</key>
+        <string>unsurprising</string>
+        <key>unsurprizingly</key>
+        <string>unsurprisingly</string>
+        <key>untill</key>
+        <string>until</string>
+        <key>untranslateable</key>
+        <string>untranslatable</string>
+        <key>unuseable</key>
+        <string>unusable</string>
+        <key>unusuable</key>
+        <string>unusable</string>
+        <key>unviersity</key>
+        <string>university</string>
+        <key>unwarrented</key>
+        <string>unwarranted</string>
+        <key>unweildly</key>
+        <string>unwieldy</string>
+        <key>unwieldly</key>
+        <string>unwieldy</string>
+        <key>upcomming</key>
+        <string>upcoming</string>
+        <key>upgradded</key>
+        <string>upgraded</string>
+        <key>upto</key>
+        <string>up to</string>
+        <key>usally</key>
+        <string>usually</string>
+        <key>useage</key>
+        <string>usage</string>
+        <key>usefull</key>
+        <string>useful</string>
+        <key>usefuly</key>
+        <string>usefully</string>
+        <key>useing</key>
+        <string>using</string>
+        <key>usualy</key>
+        <string>usually</string>
+        <key>ususally</key>
+        <string>usually</string>
+        <key>vaccum</key>
+        <string>vacuum</string>
+        <key>vaccume</key>
+        <string>vacuum</string>
+        <key>vacinity</key>
+        <string>vicinity</string>
+        <key>vaguaries</key>
+        <string>vagaries</string>
+        <key>vaieties</key>
+        <string>varieties</string>
+        <key>vailidty</key>
+        <string>validity</string>
+        <key>valetta</key>
+        <string>valletta</string>
+        <key>valuble</key>
+        <string>valuable</string>
+        <key>valueable</key>
+        <string>valuable</string>
+        <key>varations</key>
+        <string>variations</string>
+        <key>varient</key>
+        <string>variant</string>
+        <key>variey</key>
+        <string>variety</string>
+        <key>varing</key>
+        <string>varying</string>
+        <key>varities</key>
+        <string>varieties</string>
+        <key>varity</key>
+        <string>variety</string>
+        <key>vasall</key>
+        <string>vassal</string>
+        <key>vasalls</key>
+        <string>vassals</string>
+        <key>vegatarian</key>
+        <string>vegetarian</string>
+        <key>vegitable</key>
+        <string>vegetable</string>
+        <key>vegitables</key>
+        <string>vegetables</string>
+        <key>vegtable</key>
+        <string>vegetable</string>
+        <key>vehicule</key>
+        <string>vehicle</string>
+        <key>vell</key>
+        <string>well</string>
+        <key>venemous</key>
+        <string>venomous</string>
+        <key>vengance</key>
+        <string>vengeance</string>
+        <key>vengence</key>
+        <string>vengeance</string>
+        <key>verfication</key>
+        <string>verification</string>
+        <key>verison</key>
+        <string>version</string>
+        <key>verisons</key>
+        <string>versions</string>
+        <key>vermillion</key>
+        <string>vermilion</string>
+        <key>versitilaty</key>
+        <string>versatility</string>
+        <key>versitlity</key>
+        <string>versatility</string>
+        <key>vetween</key>
+        <string>between</string>
+        <key>veyr</key>
+        <string>very</string>
+        <key>vigeur</key>
+        <string>vigor</string>
+        <key>vigilence</key>
+        <string>vigilance</string>
+        <key>vigourous</key>
+        <string>vigorous</string>
+        <key>villian</key>
+        <string>villain</string>
+        <key>villification</key>
+        <string>vilification</string>
+        <key>villify</key>
+        <string>vilify</string>
+        <key>villin</key>
+        <string>villain</string>
+        <key>vincinity</key>
+        <string>vicinity</string>
+        <key>violentce</key>
+        <string>violence</string>
+        <key>virtualy</key>
+        <string>virtually</string>
+        <key>virutal</key>
+        <string>virtual</string>
+        <key>virutally</key>
+        <string>virtually</string>
+        <key>visable</key>
+        <string>visible</string>
+        <key>visably</key>
+        <string>visibly</string>
+        <key>visting</key>
+        <string>visiting</string>
+        <key>vistors</key>
+        <string>visitors</string>
+        <key>vitories</key>
+        <string>victories</string>
+        <key>volcanoe</key>
+        <string>volcano</string>
+        <key>voleyball</key>
+        <string>volleyball</string>
+        <key>volontary</key>
+        <string>voluntary</string>
+        <key>volonteer</key>
+        <string>volunteer</string>
+        <key>volonteered</key>
+        <string>volunteered</string>
+        <key>volonteering</key>
+        <string>volunteering</string>
+        <key>volonteers</key>
+        <string>volunteers</string>
+        <key>volounteer</key>
+        <string>volunteer</string>
+        <key>volounteered</key>
+        <string>volunteered</string>
+        <key>volounteering</key>
+        <string>volunteering</string>
+        <key>volounteers</key>
+        <string>volunteers</string>
+        <key>volumne</key>
+        <string>volume</string>
+        <key>vreity</key>
+        <string>variety</string>
+        <key>vrey</key>
+        <string>very</string>
+        <key>vriety</key>
+        <string>variety</string>
+        <key>vulnerablility</key>
+        <string>vulnerability</string>
+        <key>vyer</key>
+        <string>very</string>
+        <key>vyre</key>
+        <string>very</string>
+        <key>waht</key>
+        <string>what</string>
+        <key>wanna</key>
+        <string>want to</string>
+        <key>warantee</key>
+        <string>warranty</string>
+        <key>wardobe</key>
+        <string>wardrobe</string>
+        <key>warrent</key>
+        <string>warrant</string>
+        <key>warrriors</key>
+        <string>warriors</string>
+        <key>wasnt</key>
+        <string>wasn&apos;t</string>
+        <key>wass</key>
+        <string>was</string>
+        <key>watn</key>
+        <string>want</string>
+        <key>wayword</key>
+        <string>wayward</string>
+        <key>weaponary</key>
+        <string>weaponry</string>
+        <key>weas</key>
+        <string>was</string>
+        <key>wehn</key>
+        <string>when</string>
+        <key>weild</key>
+        <string>wield</string>
+        <key>weilded</key>
+        <string>wielded</string>
+        <key>wendsay</key>
+        <string>Wednesday</string>
+        <key>wensday</key>
+        <string>Wednesday</string>
+        <key>wereabouts</key>
+        <string>whereabouts</string>
+        <key>whant</key>
+        <string>want</string>
+        <key>whants</key>
+        <string>wants</string>
+        <key>whcih</key>
+        <string>which</string>
+        <key>wheras</key>
+        <string>whereas</string>
+        <key>wherease</key>
+        <string>whereas</string>
+        <key>whereever</key>
+        <string>wherever</string>
+        <key>whic</key>
+        <string>which</string>
+        <key>whihc</key>
+        <string>which</string>
+        <key>whith</key>
+        <string>with</string>
+        <key>whlch</key>
+        <string>which</string>
+        <key>whn</key>
+        <string>when</string>
+        <key>wholey</key>
+        <string>wholly</string>
+        <key>wholy</key>
+        <string>holy</string>
+        <key>whta</key>
+        <string>what</string>
+        <key>whther</key>
+        <string>whether</string>
+        <key>wich</key>
+        <string>which</string>
+        <key>widesread</key>
+        <string>widespread</string>
+        <key>wief</key>
+        <string>wife</string>
+        <key>wierd</key>
+        <string>weird</string>
+        <key>wiew</key>
+        <string>view</string>
+        <key>wih</key>
+        <string>with</string>
+        <key>wiht</key>
+        <string>with</string>
+        <key>wille</key>
+        <string>will</string>
+        <key>willingless</key>
+        <string>willingness</string>
+        <key>wirting</key>
+        <string>writing</string>
+        <key>withdrawl</key>
+        <string>withdrawal</string>
+        <key>witheld</key>
+        <string>withheld</string>
+        <key>withh</key>
+        <string>with</string>
+        <key>withing</key>
+        <string>within</string>
+        <key>withold</key>
+        <string>withhold</string>
+        <key>witht</key>
+        <string>with</string>
+        <key>witn</key>
+        <string>with</string>
+        <key>wiull</key>
+        <string>will</string>
+        <key>wnat</key>
+        <string>want</string>
+        <key>wnated</key>
+        <string>wanted</string>
+        <key>wnats</key>
+        <string>wants</string>
+        <key>wohle</key>
+        <string>whole</string>
+        <key>wokr</key>
+        <string>work</string>
+        <key>wokring</key>
+        <string>working</string>
+        <key>wonderfull</key>
+        <string>wonderful</string>
+        <key>wont</key>
+        <string>won&apos;t</string>
+        <key>wordlwide</key>
+        <string>worldwide</string>
+        <key>workststion</key>
+        <string>workstation</string>
+        <key>worls</key>
+        <string>world</string>
+        <key>worstened</key>
+        <string>worsened</string>
+        <key>woudl</key>
+        <string>would</string>
+        <key>wresters</key>
+        <string>wrestlers</string>
+        <key>wriet</key>
+        <string>write</string>
+        <key>writen</key>
+        <string>written</string>
+        <key>wroet</key>
+        <string>wrote</string>
+        <key>wrok</key>
+        <string>work</string>
+        <key>wroking</key>
+        <string>working</string>
+        <key>wtih</key>
+        <string>with</string>
+        <key>wupport</key>
+        <string>support</string>
+        <key>xenophoby</key>
+        <string>xenophobia</string>
+        <key>yaching</key>
+        <string>yachting</string>
+        <key>yaer</key>
+        <string>year</string>
+        <key>yaerly</key>
+        <string>yearly</string>
+        <key>yaers</key>
+        <string>years</string>
+        <key>yatch</key>
+        <string>yacht</string>
+        <key>yearm</key>
+        <string>year</string>
+        <key>yeasr</key>
+        <string>years</string>
+        <key>yeild</key>
+        <string>yield</string>
+        <key>yeilding</key>
+        <string>yielding</string>
+        <key>yera</key>
+        <string>year</string>
+        <key>yeras</key>
+        <string>years</string>
+        <key>yersa</key>
+        <string>years</string>
+        <key>yotube</key>
+        <string>YouTube</string>
+        <key>youre</key>
+        <string>you&apos;re</string>
+        <key>youseff</key>
+        <string>yousef</string>
+        <key>youself</key>
+        <string>yourself</string>
+        <key>ytou</key>
+        <string>you</string>
+        <key>yuo</key>
+        <string>you</string>
+        <key>zeebra</key>
+        <string>zebra</string>
+      </map>
+    </map>
+  </array>
+</llsd>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c9b4de014097f001ba1bf2e16f1312d3469a120c..5e50bd6e01217b0a91d88fa8bb8bc0a21a714981 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -148,7 +148,7 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>ApplyTextureImmediately</key>
+    <key>TextureLivePreview</key>
     <map>
       <key>Comment</key>
       <string>Preview selections in texture picker immediately</string>
@@ -335,6 +335,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>AutoReplace</key>
+    <map>
+      <key>Comment</key>
+      <string>Replaces keywords with a configured word or phrase</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
   <key>AutoAcceptNewInventory</key>
     <map>
       <key>Comment</key>
@@ -4292,6 +4303,17 @@
         <string>Boolean</string>
         <key>Value</key>
         <integer>0</integer>
+    </map>
+    <key>InventoryInboxToggleState</key>
+    <map>
+        <key>Comment</key>
+        <string>Stores the open/closed state of inventory Received items panel</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Boolean</string>
+        <key>Value</key>
+        <integer>0</integer>
     </map>
 	<key>InventoryLinking</key>
 	<map>
@@ -6356,17 +6378,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>NumpadControl</key>
-    <map>
-      <key>Comment</key>
-      <string>How numpad keys control your avatar. 0 = Like the normal arrow keys, 1 = Numpad moves avatar when numlock is off, 2 = Numpad moves avatar regardless of numlock (use this if you have no numlock)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>S32</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>ObjectCacheEnabled</key>
     <map>
       <key>Comment</key>
@@ -7274,7 +7285,7 @@
     <key>WebContentWindowLimit</key>
     <map>
       <key>Comment</key>
-      <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string>
+      <string>Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit)</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -8093,6 +8104,18 @@
     <real>0</real>
   </map>
 
+  <key>RenderDepthPrePass</key>
+  <map>
+    <key>Comment</key>
+    <string>EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  
   <key>RenderDepthOfField</key>
   <map>
     <key>Comment</key>
@@ -9172,7 +9195,7 @@
     <key>RenderUseVAO</key>
     <map>
       <key>Comment</key>
-      <string>Use GL Vertex Array Objects</string>
+      <string>[EXPERIMENTAL] Use GL Vertex Array Objects</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -9180,7 +9203,19 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>RenderVBOMappingDisable</key>
+  <key>RenderUseTransformFeedback</key>
+  <map>
+    <key>Comment</key>
+    <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+
+  <key>RenderVBOMappingDisable</key>
     <map>
       <key>Comment</key>
       <string>Disable VBO glMapBufferARB</string>
@@ -10863,7 +10898,8 @@
       <string>F32</string>
       <key>Value</key>
       <real>0.1</real>
-    </map>   <key>ToolTipFadeTime</key>
+    </map>
+    <key>ToolTipFadeTime</key>
     <map>
       <key>Comment</key>
       <string>Seconds over which tooltip fades away</string>
@@ -12227,6 +12263,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+  <key>RenderSynchronousOcclusion</key>
+  <map>
+    <key>Comment</key>
+    <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
     <key>RenderDelayVBUpdate</key>
     <map>
       <key>Comment</key>
@@ -12260,6 +12307,28 @@
       <key>Value</key>
       <real>10.0</real>
     </map>
+    <key>SpellCheck</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable spellchecking on line and text editors</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>SpellCheckDictionary</key>
+    <map>
+      <key>Comment</key>
+      <string>Current primary and secondary dictionaries used for spell checking</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>English (United States),Second Life Glossary</string>
+    </map>
     <key>UseNewWalkRun</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
index cb87b754b429e06c52c5999ece6570be92bd7950..1113a9845b275ca01562a597b60167b2c180f848 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
@@ -31,6 +31,8 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
+uniform float minimum_alpha;
+
 uniform sampler2DRect depthMap;
 uniform sampler2D diffuseMap;
 
@@ -70,9 +72,15 @@ void main()
 	
 	vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
 
+	if (diff.a < minimum_alpha)
+	{
+		discard;
+	}
+
 	vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
 	vec4 color = diff * col;
 	
+	
 	color.rgb = atmosLighting(color.rgb);
 
 	color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 75de47614cfadb6547351436aacab2e917a56609..bff87cb6aac7499a1ae030a8b6fac365c9ee19e2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -55,8 +55,6 @@ uniform float far_clip;
 
 uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
 uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
 
 uniform vec3 center;
 uniform vec3 color;
@@ -143,7 +141,8 @@ void main()
 		discard;
 	}
 		
-	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+	vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+	norm = vec3((norm.xy-0.5)*2.0, norm.z);
 	
 	norm = normalize(norm);
 	float l_dist = -dot(lv, proj_n);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 19800a8b8e16be7369e3c23376124c79dd45c2b2..f671d5b750e3123895d09710f4e6262a105036d6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -42,12 +42,13 @@ uniform sampler2DRect depthMap;
 uniform vec3 env_mat[3];
 uniform float sun_wash;
 
-uniform vec3 center;
 uniform vec3 color;
 uniform float falloff;
 uniform float size;
 
 VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
@@ -74,7 +75,7 @@ void main()
 	frag.xy *= screen_res;
 	
 	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = center.xyz-pos;
+	vec3 lv = trans_center.xyz-pos;
 	float dist2 = dot(lv,lv);
 	dist2 /= size;
 	if (dist2 > 1.0)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index cb14e6d4e8b164235c9c53ecbb72081ea167b1fd..9491421236d49d0ad05f8220274498c75809a54e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -24,16 +24,22 @@
  */
 
 uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
 
 ATTRIBUTE vec3 position;
 
+uniform vec3 center;
+uniform float size;
+
 VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
 
 void main()
 {
 	//transform vertex
-	vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	vec3 p = position*sqrt(size)+center;
+	vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
 	vary_fragcoord = pos;
-		
+	trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;
 	gl_Position = pos;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..6195e2f1ecb30ff4d115595edae972e96f673184
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -0,0 +1,44 @@
+/** 
+ * @file shadowCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec4 post_pos;
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+	//transform vertex
+	vec3 p = position*box_size+box_center;
+	vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
+	
+	post_pos = pos;
+	
+	gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 7ed8ed33701ed891d78ca2a7edd16d2e400d1c23..cca63872de2142faa13bce99ad2b4e703e1a73bc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -24,18 +24,21 @@
  */
 
  
-#extension GL_ARB_texture_rectangle : enable
-
 #ifdef DEFINE_GL_FRAGCOLOR
 out vec4 frag_color;
 #else
 #define frag_color gl_FragColor
 #endif
 
+//class 1 -- no shadows
+
+#extension GL_ARB_texture_rectangle : enable
+
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect depthMap;
 uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
 uniform sampler2D noiseMap;
 uniform sampler2D projectionMap;
 
@@ -46,6 +49,7 @@ uniform vec3 proj_n;
 uniform float proj_focus; //distance from plane to begin blurring
 uniform float proj_lod;  //(number of mips in proj map)
 uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
 uniform float proj_ambiance;
 uniform float near_clip;
 uniform float far_clip;
@@ -53,19 +57,66 @@ uniform float far_clip;
 uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
 uniform float sun_wash;
 
-uniform vec3 center;
 uniform vec3 color;
 uniform float falloff;
 uniform float size;
 
 VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
 
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+	vec4 ret = texture2DLod(projectionMap, tc, lod);
+	
+	vec2 dist = tc-vec2(0.5);
+	
+	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+	
+	float d = dot(dist,dist);
+		
+	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+	
+	return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+	vec4 ret = texture2DLod(projectionMap, tc, lod);
+	
+	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+	
+	float det = min(lod/(proj_lod*0.5), 1.0);
+	
+	float d = min(dist.x, dist.y);
+	
+	float edge = 0.25*det;
+		
+	ret *= clamp(d/edge, 0.0, 1.0);
+	
+	return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+	vec4 ret = texture2DLod(projectionMap, tc, lod);
+	
+	vec2 dist = tc-vec2(0.5);
+	
+	float d = dot(dist,dist);
+		
+	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+	
+	return ret;
+}
+
+
 vec4 getPosition(vec2 pos_screen)
 {
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
+	float depth = texture2DRect(depthMap, pos_screen.xy).r;
 	vec2 sc = pos_screen.xy*2.0;
 	sc /= screen_res;
 	sc -= vec2(1.0,1.0);
@@ -84,16 +135,16 @@ void main()
 	frag.xy *= screen_res;
 	
 	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = center.xyz-pos.xyz;
+	vec3 lv = trans_center.xyz-pos.xyz;
 	float dist2 = dot(lv,lv);
 	dist2 /= size;
 	if (dist2 > 1.0)
 	{
 		discard;
 	}
-	
+		
 	vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+	norm = vec3((norm.xy-0.5)*2.0, norm.z);
 	
 	norm = normalize(norm);
 	float l_dist = -dot(lv, proj_n);
@@ -107,7 +158,11 @@ void main()
 	proj_tc.xyz /= proj_tc.w;
 	
 	float fa = falloff+1.0;
-	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+	if (dist_atten <= 0.0)
+	{
+		discard;
+	}
 	
 	lv = proj_origin-pos.xyz;
 	lv = normalize(lv);
@@ -125,32 +180,32 @@ void main()
 		proj_tc.y > 0.0)
 	{
 		float lit = 0.0;
+		float amb_da = proj_ambiance;
+		
 		if (da > 0.0)
 		{
 			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
 			float lod = diff * proj_lod;
 			
-			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
 		
 			vec3 lcol = color.rgb * plcol.rgb * plcol.a;
 			
 			lit = da * dist_atten * noise;
 			
 			col = lcol*lit*diff_tex;
+			amb_da += (da*0.5)*proj_ambiance;
 		}
 		
-		float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
-		float lod = diff * proj_lod;
-		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
-		//float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
-		float amb_da = proj_ambiance;
-		
+		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+							
 		amb_da += (da*da*0.5+0.5)*proj_ambiance;
-			
+				
 		amb_da *= dist_atten * noise;
-		
+			
 		amb_da = min(amb_da, 1.0-lit);
-		
+			
 		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
 	}
 	
@@ -168,18 +223,22 @@ void main()
 		{
 			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
 			
-			vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
 
 			if (stc.z > 0.0)
 			{
-				stc.xy /= stc.z+proj_near;
-					
+				stc.xy /= stc.w;
+
+				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+				
+				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+								
 				if (stc.x < 1.0 &&
 					stc.y < 1.0 &&
 					stc.x > 0.0 &&
 					stc.y > 0.0)
 				{
-					vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
 					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
 				}
 			}
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..ac2bc8703b9530cf6804c18d4bc705e8425fab80
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
@@ -0,0 +1,46 @@
+/** 
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform vec4 color;
+uniform vec4 clip_plane;
+
+VARYING vec3 vary_position;
+
+
+void main() 
+{
+	if (dot(vary_position,clip_plane.xyz)+clip_plane.w < 0.0)
+	{
+		discard;
+	}
+
+	frag_color = color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..e376b25a71fe27e9391a1551b60d94039ca98786
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
@@ -0,0 +1,38 @@
+/** 
+ * @file debugV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 vary_position;
+
+void main()
+{
+	vary_position = (modelview_matrix*vec4(position.xyz,1.0)).xyz;
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..5c479d27a91cbb7f74e04686d500919cfe7dd775
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
@@ -0,0 +1,38 @@
+/** 
+ * @file occlusionCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+	vec3 p = position*box_size+box_center;
+	gl_Position = modelview_projection_matrix * vec4(p.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..44f1aa34a0313f0451b26df3c6a78afd8dbb2364
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file binormalV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat3 normal_matrix;
+
+ATTRIBUTE vec3 binormal;
+
+VARYING vec4 binormal_out;
+
+void main()
+{
+	binormal_out = vec4(normal_matrix * binormal, 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..59c4a7d8958435eb1a1ddeabac33e45b8bcc2b19
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file colorV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform int color_in;
+
+ATTRIBUTE vec3 position;
+
+VARYING int color_out;
+
+void main()
+{
+	color_out = color_in;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..a213aa0ae8500604e5c961ca411337d2d9956dc2
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file normalV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat3 normal_matrix;
+
+ATTRIBUTE vec3 normal;
+
+VARYING vec4 normal_out;
+
+void main()
+{
+	normal_out = vec4(normalize(normal_matrix * normal), 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..01eed18de431e81be84eb44a1cc0d4e13cccce6c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
@@ -0,0 +1,40 @@
+/**
+ * @file positionV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_matrix;
+
+uniform int texture_index_in;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 position_out;
+VARYING int texture_index_out;
+
+void main()
+{
+	texture_index_out = texture_index_in;
+	position_out = (modelview_matrix*vec4(position, 1.0)).xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..0e074f3cec6b33139b39419b6e213603a6925bd0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
@@ -0,0 +1,35 @@
+/**
+ * @file texcoordV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 texcoord_out;
+
+void main()
+{
+	texcoord_out = texcoord0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
index ba6f3ace53f175bf91c683281f11208da5a60b6f..2093fc37dc3330a24b9971ce0718805de407444c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
@@ -31,6 +31,8 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
+uniform float minimum_alpha;
+
 uniform sampler2DRectShadow shadowMap0;
 uniform sampler2DRectShadow shadowMap1;
 uniform sampler2DRectShadow shadowMap2;
@@ -97,6 +99,13 @@ void main()
 	float shadow = 0.0;
 	vec4 pos = vec4(vary_position, 1.0);
 	
+	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+
+	if (diff.a < minimum_alpha)
+	{
+		discard;
+	}
+	
 	vec4 spos = pos;
 		
 	if (spos.z > -shadow_clip.w)
@@ -164,8 +173,6 @@ void main()
 		shadow = 1.0;
 	}
 	
-	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
-
 	vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
 	vec4 color = diff * col;
 	
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 99a277fbfcced0456bafad4b1af369a961c4eb11..ab077d9e026a50751235a098e08fb8d4116c1c09 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -31,8 +31,6 @@ out vec4 frag_color;
 #define frag_color gl_FragColor
 #endif
 
-VARYING vec4 vertex_color;
-
 uniform sampler2DRect diffuseRect;
 uniform sampler2DRect specularRect;
 uniform sampler2DRect depthMap;
@@ -49,6 +47,7 @@ uniform vec3 proj_n;
 uniform float proj_focus; //distance from plane to begin blurring
 uniform float proj_lod;  //(number of mips in proj map)
 uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
 uniform float proj_ambiance;
 uniform float near_clip;
 uniform float far_clip;
@@ -58,16 +57,65 @@ uniform float sun_wash;
 uniform int proj_shadow_idx;
 uniform float shadow_fade;
 
-VARYING vec4 vary_light;
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
 
+VARYING vec3 trans_center;
 VARYING vec4 vary_fragcoord;
 uniform vec2 screen_res;
 
 uniform mat4 inv_proj;
 
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+	vec4 ret = texture2DLod(projectionMap, tc, lod);
+	
+	vec2 dist = tc-vec2(0.5);
+	
+	float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+	
+	float d = dot(dist,dist);
+		
+	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+	
+	return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+	vec4 ret = texture2DLod(projectionMap, tc, lod);
+	
+	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+	
+	float det = min(lod/(proj_lod*0.5), 1.0);
+	
+	float d = min(dist.x, dist.y);
+	
+	float edge = 0.25*det;
+		
+	ret *= clamp(d/edge, 0.0, 1.0);
+	
+	return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+	vec4 ret = texture2DLod(projectionMap, tc, lod);
+	
+	vec2 dist = tc-vec2(0.5);
+	
+	float d = dot(dist,dist);
+		
+	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+	
+	return ret;
+}
+
+
 vec4 getPosition(vec2 pos_screen)
 {
-	float depth = texture2DRect(depthMap, pos_screen.xy).a;
+	float depth = texture2DRect(depthMap, pos_screen.xy).r;
 	vec2 sc = pos_screen.xy*2.0;
 	sc /= screen_res;
 	sc -= vec2(1.0,1.0);
@@ -85,6 +133,15 @@ void main()
 	frag.xyz = frag.xyz*0.5+0.5;
 	frag.xy *= screen_res;
 	
+	vec3 pos = getPosition(frag.xy).xyz;
+	vec3 lv = trans_center.xyz-pos.xyz;
+	float dist2 = dot(lv,lv);
+	dist2 /= size;
+	if (dist2 > 1.0)
+	{
+		discard;
+	}
+	
 	float shadow = 1.0;
 	
 	if (proj_shadow_idx >= 0)
@@ -96,15 +153,6 @@ void main()
 		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
 	}
 	
-	vec3 pos = getPosition(frag.xy).xyz;
-	vec3 lv = vary_light.xyz-pos.xyz;
-	float dist2 = dot(lv,lv);
-	dist2 /= vary_light.w;
-	if (dist2 > 1.0)
-	{
-		discard;
-	}
-	
 	vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
 	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
 	
@@ -119,8 +167,12 @@ void main()
 	
 	proj_tc.xyz /= proj_tc.w;
 	
-	float fa = vertex_color.a+1.0;
-	float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+	float fa = falloff+1.0;
+	float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+	if (dist_atten <= 0.0)
+	{
+		discard;
+	}
 	
 	lv = proj_origin-pos.xyz;
 	lv = normalize(lv);
@@ -138,37 +190,33 @@ void main()
 		proj_tc.y > 0.0)
 	{
 		float lit = 0.0;
+		float amb_da = proj_ambiance;
+		
 		if (da > 0.0)
 		{
 			float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
 			float lod = diff * proj_lod;
 			
-			vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
 		
-			vec3 lcol = vertex_color.rgb * plcol.rgb * plcol.a;
+			vec3 lcol = color.rgb * plcol.rgb * plcol.a;
 			
 			lit = da * dist_atten * noise;
 			
 			col = lcol*lit*diff_tex*shadow;
-		}
-		
-		float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
-		float lod = diff * proj_lod;
-		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
-		//float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
-		float amb_da = proj_ambiance;
-		if (da > 0.0)
-		{
 			amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
 		}
 		
+		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+							
 		amb_da += (da*da*0.5+0.5)*proj_ambiance;
-			
+				
 		amb_da *= dist_atten * noise;
-		
+			
 		amb_da = min(amb_da, 1.0-lit);
-		
-		col += amb_da*vertex_color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+			
+		col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
 	}
 	
 	
@@ -185,19 +233,23 @@ void main()
 		{
 			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
 			
-			vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
 
 			if (stc.z > 0.0)
 			{
-				stc.xy /= stc.z+proj_near;
-					
+				stc.xy /= stc.w;
+
+				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+				
+				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+								
 				if (stc.x < 1.0 &&
 					stc.y < 1.0 &&
 					stc.x > 0.0 &&
 					stc.y > 0.0)
 				{
-					vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
-					col += dist_atten*scol.rgb*vertex_color.rgb*scol.a*spec.rgb*shadow;
+					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+					col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
 				}
 			}
 		}
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e8a109e66150961b43419ab017527faf7ca0d363..eeb632acaf2f590fdf0b84fed0fd0b2e7f6f2bba 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -520,6 +520,7 @@ Disregard128DefaultDrawDistance	1	0
 list ATIOldDriver
 RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
+RenderVBOEnable				1	0
 
 // ATI cards generally perform better when not using VBOs for streaming data
 
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index 398a64378e0d6969dd0838fd95ff5ff3d1ea0899..a945f7a6938d7938b861bc82d4fed78c969f6deb 100644
--- a/indra/newview/featuretable_xp.txt
+++ b/indra/newview/featuretable_xp.txt
@@ -517,6 +517,7 @@ Disregard128DefaultDrawDistance	1	0
 list ATIOldDriver
 RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
+RenderVBOEnable				1	0
 
 // ATI cards generally perform better when not using VBOs for streaming data
 
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 336760475354c6f094422367d596295088a49cd3..a6776d4c8d8c556763302a828d3b0aa62fe61dd4 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -81,6 +81,7 @@
 #include "llviewermenu.h"
 #include "llviewerobjectlist.h"
 #include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
@@ -112,6 +113,105 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds
 // The agent instance.
 LLAgent gAgent;
 
+class LLTeleportRequest
+{
+public:
+	enum EStatus
+	{
+		kPending,
+		kStarted,
+		kFailed,
+		kRestartPending
+	};
+
+	LLTeleportRequest();
+	virtual ~LLTeleportRequest();
+
+	EStatus getStatus() const          {return mStatus;};
+	void    setStatus(EStatus pStatus) {mStatus = pStatus;};
+
+	virtual bool canRestartTeleport();
+
+	virtual void startTeleport() = 0;
+	virtual void restartTeleport();
+
+protected:
+
+private:
+	EStatus mStatus;
+};
+
+class LLTeleportRequestViaLandmark : public LLTeleportRequest
+{
+public:
+	LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
+	virtual ~LLTeleportRequestViaLandmark();
+
+	virtual bool canRestartTeleport();
+
+	virtual void startTeleport();
+	virtual void restartTeleport();
+
+protected:
+	inline const LLUUID &getLandmarkId() const {return mLandmarkId;};
+
+private:
+	LLUUID mLandmarkId;
+};
+
+class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark
+{
+public:
+	LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike);
+	virtual ~LLTeleportRequestViaLure();
+
+	virtual bool canRestartTeleport();
+
+	virtual void startTeleport();
+
+protected:
+	inline BOOL isLureGodLike() const {return mIsLureGodLike;};
+
+private:
+	BOOL mIsLureGodLike;
+};
+
+class LLTeleportRequestViaLocation : public LLTeleportRequest
+{
+public:
+	LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
+	virtual ~LLTeleportRequestViaLocation();
+
+	virtual bool canRestartTeleport();
+
+	virtual void startTeleport();
+	virtual void restartTeleport();
+
+protected:
+	inline const LLVector3d &getPosGlobal() const {return mPosGlobal;};
+
+private:
+	LLVector3d mPosGlobal;
+};
+
+
+class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation
+{
+public:
+	LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
+	virtual ~LLTeleportRequestViaLocationLookAt();
+
+	virtual bool canRestartTeleport();
+
+	virtual void startTeleport();
+	virtual void restartTeleport();
+
+protected:
+
+private:
+
+};
+
 //--------------------------------------------------------------------
 // Statics
 //
@@ -245,6 +345,17 @@ LLAgent::LLAgent() :
 	mAgentAccess(new LLAgentAccess(gSavedSettings)),
 	mCanEditParcel(false),
 	mTeleportSourceSLURL(new LLSLURL),
+	mTeleportRequest(),
+	mTeleportFinishedSlot(),
+	mTeleportFailedSlot(),
+	mIsMaturityRatingChangingDuringTeleport(false),
+	mMaturityRatingChange(0U),
+	mIsDoSendMaturityPreferenceToServer(false),
+	mMaturityPreferenceRequestId(0U),
+	mMaturityPreferenceResponseId(0U),
+	mMaturityPreferenceNumRetries(0U),
+	mLastKnownRequestMaturity(SIM_ACCESS_MIN),
+	mLastKnownResponseMaturity(SIM_ACCESS_MIN),
 	mTeleportState( TELEPORT_NONE ),
 	mRegionp(NULL),
 
@@ -330,9 +441,21 @@ void LLAgent::init()
 
 	gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
 	gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
+	mLastKnownResponseMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity"));
+	mLastKnownRequestMaturity = mLastKnownResponseMaturity;
+	mIsDoSendMaturityPreferenceToServer = true;
 
 	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
 
+	if (!mTeleportFinishedSlot.connected())
+	{
+		mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this));
+	}
+	if (!mTeleportFailedSlot.connected())
+	{
+		mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
+	}
+
 	mInitialized = TRUE;
 }
 
@@ -342,6 +465,14 @@ void LLAgent::init()
 void LLAgent::cleanup()
 {
 	mRegionp = NULL;
+	if (mTeleportFinishedSlot.connected())
+	{
+		mTeleportFinishedSlot.disconnect();
+	}
+	if (mTeleportFailedSlot.connected())
+	{
+		mTeleportFailedSlot.disconnect();
+	}
 }
 
 //-----------------------------------------------------------------------------
@@ -2371,49 +2502,278 @@ bool LLAgent::isAdult() const
 	return mAgentAccess->isAdult();
 }
 
-void LLAgent::setTeen(bool teen)
-{
-	mAgentAccess->setTeen(teen);
-}
-
 //static 
 int LLAgent::convertTextToMaturity(char text)
 {
 	return LLAgentAccess::convertTextToMaturity(text);
 }
 
-bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
+class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
 {
-	if (!getRegion())
-		return false;
+public:
+	LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
+	virtual ~LLMaturityPreferencesResponder();
+
+	virtual void result(const LLSD &pContent);
+	virtual void error(U32 pStatus, const std::string& pReason);
+
+protected:
+
+private:
+	U8 parseMaturityFromServerResponse(const LLSD &pContent);
+
+	LLAgent                                  *mAgent;
+	U8                                       mPreferredMaturity;
+	U8                                       mPreviousMaturity;
+};
+
+LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
+	: LLHTTPClient::Responder(),
+	mAgent(pAgent),
+	mPreferredMaturity(pPreferredMaturity),
+	mPreviousMaturity(pPreviousMaturity)
+{
+}
+
+LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
+{
+}
+
+void LLMaturityPreferencesResponder::result(const LLSD &pContent)
+{
+	U8 actualMaturity = parseMaturityFromServerResponse(pContent);
+
+	if (actualMaturity != mPreferredMaturity)
+	{
+		llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
+			<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '"
+			<< LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast<U32>(actualMaturity) << ", llsd:"
+			<< pContent << "]" << llendl;
+	}
+	mAgent->handlePreferredMaturityResult(actualMaturity);
+}
+
+void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason)
+{
+	llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
+		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '"
+		<< pReason << "' [status:" << pStatus << "]" << llendl;
+	mAgent->handlePreferredMaturityError();
+}
+
+U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
+{
+	// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior.  In the old server code,
+	// if you attempted to change the preferred maturity to the same value, the response content would be an
+	// undefined LLSD block.  In the new server code with pathfinding, the response content should always be
+	// defined.  Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
+	// into server trunk and fully deployed.
+	U8 maturity = SIM_ACCESS_MIN;
+	if (pContent.isUndefined())
+	{
+		maturity = mPreferredMaturity;
+	}
+	else
+	{
+		llassert(!pContent.isUndefined());
+		llassert(pContent.isMap());
 	
-	// Update agent access preference on the server
-	std::string url = getRegion()->getCapability("UpdateAgentInformation");
-	if (!url.empty())
+		if (!pContent.isUndefined() && pContent.isMap())
+		{
+			// stinson 05/24/2012 Pathfinding regions have re-defined the response syntax.  The if statement catches
+			// the new syntax, and the else statement catches the old syntax.  After pathfinding is merged into
+			// server trunk and fully deployed, we can remove the else statement.
+			if (pContent.has("access_prefs"))
+			{
+				llassert(pContent.has("access_prefs"));
+				llassert(pContent.get("access_prefs").isMap());
+				llassert(pContent.get("access_prefs").has("max"));
+				llassert(pContent.get("access_prefs").get("max").isString());
+				if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") &&
+					pContent.get("access_prefs").get("max").isString())
+				{
+					LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
+					LLStringUtil::trim(actualPreference);
+					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
+				}
+			}
+			else if (pContent.has("max"))
+			{
+				llassert(pContent.get("max").isString());
+				if (pContent.get("max").isString())
+				{
+					LLSD::String actualPreference = pContent.get("max").asString();
+					LLStringUtil::trim(actualPreference);
+					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
+				}
+			}
+		}
+	}
+
+	return maturity;
+}
+
+void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
+{
+	// Update the number of responses received
+	++mMaturityPreferenceResponseId;
+	llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId);
+
+	// Update the last known server maturity response
+	mLastKnownResponseMaturity = pServerMaturity;
+
+	// Ignore all responses if we know there are more unanswered requests that are expected
+	if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)
 	{
-		// Set new access preference
-		LLSD access_prefs = LLSD::emptyMap();
-		if (preferredMaturity == SIM_ACCESS_PG)
+		// If we received a response that matches the last known request, then we are good
+		if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
 		{
-			access_prefs["max"] = "PG";
+			mMaturityPreferenceNumRetries = 0;
+			reportPreferredMaturitySuccess();
+			llassert(static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity);
 		}
-		else if (preferredMaturity == SIM_ACCESS_MATURE)
+		// Else, the viewer is out of sync with the server, so let's try to re-sync with the
+		// server by re-sending our last known request.  Cap the re-tries at 3 just to be safe.
+		else if (++mMaturityPreferenceNumRetries <= 3)
 		{
-			access_prefs["max"] = "M";
+			llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '"
+				<< LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl;
+			sendMaturityPreferenceToServer(mLastKnownRequestMaturity);
 		}
-		if (preferredMaturity == SIM_ACCESS_ADULT)
+		// Else, the viewer is style out of sync with the server after 3 retries, so inform the user
+		else
 		{
-			access_prefs["max"] = "A";
+			mMaturityPreferenceNumRetries = 0;
+			reportPreferredMaturityError();
+		}
+	}
+}
+
+void LLAgent::handlePreferredMaturityError()
+{
+	// Update the number of responses received
+	++mMaturityPreferenceResponseId;
+	llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId);
+
+	// Ignore all responses if we know there are more unanswered requests that are expected
+	if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)
+	{
+		mMaturityPreferenceNumRetries = 0;
+
+		// If we received a response that matches the last known request, then we are synced with
+		// the server, but not quite sure why we are
+		if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
+		{
+			llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity)
+				<< "' seems to be in sync with the server" << llendl;
+			reportPreferredMaturitySuccess();
+		}
+		// Else, the more likely case is that the last request does not match the last response,
+		// so inform the user
+		else
+		{
+			reportPreferredMaturityError();
+		}
+	}
+}
+
+void LLAgent::reportPreferredMaturitySuccess()
+{
+	// If there is a pending teleport request waiting for the maturity preference to be synced with
+	// the server, let's start the pending request
+	if (hasPendingTeleportRequest())
+	{
+		startTeleportRequest();
+	}
+}
+
+void LLAgent::reportPreferredMaturityError()
+{
+	// If there is a pending teleport request waiting for the maturity preference to be synced with
+	// the server, we were unable to successfully sync with the server on maturity preference, so let's
+	// just raise the screen.
+	mIsMaturityRatingChangingDuringTeleport = false;
+	if (hasPendingTeleportRequest())
+	{
+		setTeleportState(LLAgent::TELEPORT_NONE);
+	}
+
+	// Get the last known maturity request from the user activity
+	std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity);
+	LLStringUtil::toLower(preferredMaturity);
+
+	// Get the last known maturity response from the server
+	std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity);
+	LLStringUtil::toLower(actualMaturity);
+
+	// Notify the user
+	LLSD args = LLSD::emptyMap();
+	args["PREFERRED_MATURITY"] = preferredMaturity;
+	args["ACTUAL_MATURITY"] = actualMaturity;
+	LLNotificationsUtil::add("MaturityChangeError", args);
+
+	// Check the saved settings to ensure that we are consistent.  If we are not consistent, update
+	// the viewer, but do not send anything to server
+	U8 localMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity"));
+	if (localMaturity != mLastKnownResponseMaturity)
+	{
+		bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer;
+		mIsDoSendMaturityPreferenceToServer = false;
+		llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl;
+		gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(mLastKnownResponseMaturity));
+		mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer;
+	}
+}
+
+bool LLAgent::isMaturityPreferenceSyncedWithServer() const
+{
+	return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId);
+}
+
+void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
+{
+	// Only send maturity preference to the server if enabled
+	if (mIsDoSendMaturityPreferenceToServer)
+	{
+		// Increment the number of requests.  The handlers manage a separate count of responses.
+		++mMaturityPreferenceRequestId;
+
+		// Update the last know maturity request
+		mLastKnownRequestMaturity = pPreferredMaturity;
+
+		// Create a response handler
+		LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity));
+
+		// If we don't have a region, report it as an error
+		if (getRegion() == NULL)
+		{
+			responderPtr->error(0U, "region is not defined");
+		}
+		else
+		{
+			// Find the capability to send maturity preference
+			std::string url = getRegion()->getCapability("UpdateAgentInformation");
+
+			// If the capability is not defined, report it as an error
+			if (url.empty())
+			{
+				responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region");
+			}
+			else
+			{
+				// Set new access preference
+				LLSD access_prefs = LLSD::emptyMap();
+				access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
+
+				LLSD body = LLSD::emptyMap();
+				body["access_prefs"] = access_prefs;
+				llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
+					<< "' via capability to: " << url << llendl;
+				LLSD headers;
+				LLHTTPClient::post(url, body, responderPtr, headers, 30.0f);
+			}
 		}
-		
-		LLSD body = LLSD::emptyMap();
-		body["access_prefs"] = access_prefs;
-		llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
-		<< url << llendl;
-		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());    // Ignore response
-		return true;
 	}
-	return false;
 }
 
 BOOL LLAgent::getAdminOverride() const	
@@ -2436,11 +2796,6 @@ void LLAgent::setGodLevel(U8 god_level)
 	mAgentAccess->setGodLevel(god_level);
 }
 
-void LLAgent::setAOTransition()
-{
-	mAgentAccess->setTransition();
-}
-
 const LLAgentAccess& LLAgent::getAgentAccess()
 {
 	return *mAgentAccess;
@@ -2451,9 +2806,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue)
 	return mAgentAccess->canSetMaturity(newvalue.asInteger());
 }
 
-void LLAgent::handleMaturity(const LLSD& newvalue)
+void LLAgent::handleMaturity(const LLSD &pNewValue)
 {
-	sendMaturityPreferenceToServer(newvalue.asInteger());
+	sendMaturityPreferenceToServer(static_cast<U8>(pNewValue.asInteger()));
 }
 
 //----------------------------------------------------------------------------
@@ -3388,7 +3743,7 @@ void LLAgent::clearVisualParams(void *data)
 // protected
 bool LLAgent::teleportCore(bool is_local)
 {
-	if(TELEPORT_NONE != mTeleportState)
+	if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))
 	{
 		llwarns << "Attempt to teleport when already teleporting." << llendl;
 		return false;
@@ -3466,6 +3821,102 @@ bool LLAgent::teleportCore(bool is_local)
 	return true;
 }
 
+bool LLAgent::hasRestartableFailedTeleportRequest()
+{
+	return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) &&
+		mTeleportRequest->canRestartTeleport());
+}
+
+void LLAgent::restartFailedTeleportRequest()
+{
+	if (hasRestartableFailedTeleportRequest())
+	{
+		mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending);
+		startTeleportRequest();
+	}
+}
+
+void LLAgent::clearTeleportRequest()
+{
+	mTeleportRequest.reset();
+}
+
+void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
+{
+	mIsMaturityRatingChangingDuringTeleport = true;
+	mMaturityRatingChange = pMaturityRatingChange;
+}
+
+bool LLAgent::hasPendingTeleportRequest()
+{
+	return ((mTeleportRequest != NULL) &&
+		((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) ||
+		(mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending)));
+}
+
+void LLAgent::startTeleportRequest()
+{
+	if (hasPendingTeleportRequest())
+	{
+		if  (!isMaturityPreferenceSyncedWithServer())
+		{
+			gTeleportDisplay = TRUE;
+			setTeleportState(TELEPORT_PENDING);
+		}
+		else
+		{
+			switch (mTeleportRequest->getStatus())
+			{
+			case LLTeleportRequest::kPending :
+				mTeleportRequest->setStatus(LLTeleportRequest::kStarted);
+				mTeleportRequest->startTeleport();
+				break;
+			case LLTeleportRequest::kRestartPending :
+				llassert(mTeleportRequest->canRestartTeleport());
+				mTeleportRequest->setStatus(LLTeleportRequest::kStarted);
+				mTeleportRequest->restartTeleport();
+				break;
+			default :
+				llassert(0);
+				break;
+			}
+		}
+	}
+}
+
+void LLAgent::handleTeleportFinished()
+{
+	clearTeleportRequest();
+	if (mIsMaturityRatingChangingDuringTeleport)
+	{
+		// notify user that the maturity preference has been changed
+		std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange);
+		LLStringUtil::toLower(maturityRating);
+		LLSD args;
+		args["RATING"] = maturityRating;
+		LLNotificationsUtil::add("PreferredMaturityChanged", args);
+		mIsMaturityRatingChangingDuringTeleport = false;
+	}
+}
+
+void LLAgent::handleTeleportFailed()
+{
+	if (mTeleportRequest != NULL)
+	{
+		mTeleportRequest->setStatus(LLTeleportRequest::kFailed);
+	}
+	if (mIsMaturityRatingChangingDuringTeleport)
+	{
+		// notify user that the maturity preference has been changed
+		std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange);
+		LLStringUtil::toLower(maturityRating);
+		LLSD args;
+		args["RATING"] = maturityRating;
+		LLNotificationsUtil::add("PreferredMaturityChanged", args);
+		mIsMaturityRatingChangingDuringTeleport = false;
+	}
+}
+
 void LLAgent::teleportRequest(
 	const U64& region_handle,
 	const LLVector3& pos_local,
@@ -3497,6 +3948,12 @@ void LLAgent::teleportRequest(
 
 // Landmark ID = LLUUID::null means teleport home
 void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
+{
+	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
+	startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
 {
 	LLViewerRegion *regionp = getRegion();
 	if(regionp && teleportCore())
@@ -3512,6 +3969,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
 }
 
 void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
+{
+	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
+	startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
 {
 	LLViewerRegion* regionp = getRegion();
 	if(regionp && teleportCore())
@@ -3544,23 +4007,32 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
 // James Cook, July 28, 2005
 void LLAgent::teleportCancel()
 {
-	LLViewerRegion* regionp = getRegion();
-	if(regionp)
+	if (!hasPendingTeleportRequest())
 	{
-		// send the message
-		LLMessageSystem* msg = gMessageSystem;
-		msg->newMessage("TeleportCancel");
-		msg->nextBlockFast(_PREHASH_Info);
-		msg->addUUIDFast(_PREHASH_AgentID, getID());
-		msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
-		sendReliableMessage();
-	}	
-	gTeleportDisplay = FALSE;
+		LLViewerRegion* regionp = getRegion();
+		if(regionp)
+		{
+			// send the message
+			LLMessageSystem* msg = gMessageSystem;
+			msg->newMessage("TeleportCancel");
+			msg->nextBlockFast(_PREHASH_Info);
+			msg->addUUIDFast(_PREHASH_AgentID, getID());
+			msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
+			sendReliableMessage();
+		}	
+	}
+	clearTeleportRequest();
 	gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 }
 
 
 void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
+{
+	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
+	startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
 {
 	LLViewerRegion* regionp = getRegion();
 	U64 handle = to_region_handle(pos_global);
@@ -3603,6 +4075,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
 
 // Teleport to global position, but keep facing in the same direction 
 void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
+{
+	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
+	startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global)
 {
 	mbTeleportKeepsLookAt = true;
 	gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);	// detach camera form avatar, so it keeps direction
@@ -4045,5 +4523,149 @@ LLAgentQueryManager::~LLAgentQueryManager()
 {
 }
 
-// EOF
+//-----------------------------------------------------------------------------
+// LLTeleportRequest
+//-----------------------------------------------------------------------------
+
+LLTeleportRequest::LLTeleportRequest()
+	: mStatus(kPending)
+{
+}
+
+LLTeleportRequest::~LLTeleportRequest()
+{
+}
 
+bool LLTeleportRequest::canRestartTeleport()
+{
+	return false;
+}
+
+void LLTeleportRequest::restartTeleport()
+{
+	llassert(0);
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLandmark
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
+	: LLTeleportRequest(),
+	mLandmarkId(pLandmarkId)
+{
+}
+
+LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
+{
+}
+
+bool LLTeleportRequestViaLandmark::canRestartTeleport()
+{
+	return true;
+}
+
+void LLTeleportRequestViaLandmark::startTeleport()
+{
+	gAgent.doTeleportViaLandmark(getLandmarkId());
+}
+
+void LLTeleportRequestViaLandmark::restartTeleport()
+{
+	gAgent.doTeleportViaLandmark(getLandmarkId());
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLure
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike)
+	: LLTeleportRequestViaLandmark(pLureId),
+	mIsLureGodLike(pIsLureGodLike)
+{
+}
+
+LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
+{
+}
+
+bool LLTeleportRequestViaLure::canRestartTeleport()
+{
+	// stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions
+	// The current scenario is as follows:
+	//    1. User A initializes a request for User B to teleport via lure
+	//    2. User B accepts the teleport via lure request
+	//    3. The server sees the init request from User A and the accept request from User B and matches them up
+	//    4. The server then removes the paired requests up from the "queue"
+	//    5. The server then fails User B's teleport for reason of maturity level (for example)
+	//    6. User B's viewer prompts user to increase their maturity level profile value.
+	//    7. User B confirms and accepts increase in maturity level
+	//    8. User B's viewer then attempts to teleport via lure again
+	//    9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4
+
+	return false;
+}
+
+void LLTeleportRequestViaLure::startTeleport()
+{
+	gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike());
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLocation
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal)
+	: LLTeleportRequest(),
+	mPosGlobal(pPosGlobal)
+{
+}
+
+LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
+{
+}
+
+bool LLTeleportRequestViaLocation::canRestartTeleport()
+{
+	return true;
+}
+
+void LLTeleportRequestViaLocation::startTeleport()
+{
+	gAgent.doTeleportViaLocation(getPosGlobal());
+}
+
+void LLTeleportRequestViaLocation::restartTeleport()
+{
+	gAgent.doTeleportViaLocation(getPosGlobal());
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLocationLookAt
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal)
+	: LLTeleportRequestViaLocation(pPosGlobal)
+{
+}
+
+LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
+{
+}
+
+bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
+{
+	return true;
+}
+
+void LLTeleportRequestViaLocationLookAt::startTeleport()
+{
+	gAgent.doTeleportViaLocationLookAt(getPosGlobal());
+}
+
+void LLTeleportRequestViaLocationLookAt::restartTeleport()
+{
+	gAgent.doTeleportViaLocationLookAt(getPosGlobal());
+}
+
+// EOF
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 740770bbdf26b0cbea117d436f8e38726b16d66f..a505d5bbaea6378e6e95fdc1519e899b131fd3ed 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -35,6 +35,8 @@
 #include "llcoordframe.h"			// for mFrameAgent
 #include "llvoavatardefines.h"
 
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
 #include <boost/signals2.hpp>
 
 extern const BOOL 	ANIMATE;
@@ -56,6 +58,9 @@ class LLAgentAccess;
 class LLSLURL;
 class LLPauseRequestHandle;
 class LLUIColor;
+class LLTeleportRequest;
+
+typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr;
 
 //--------------------------------------------------------------------
 // Types
@@ -539,7 +544,8 @@ class LLAgent : public LLOldEvents::LLObservable
 		TELEPORT_MOVING = 3,		// Viewer has received destination location from source simulator
 		TELEPORT_START_ARRIVAL = 4,	// Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
 		TELEPORT_ARRIVING = 5,		// Make the user wait while content "pre-caches"
-		TELEPORT_LOCAL = 6			// Teleporting in-sim without showing the progress screen
+		TELEPORT_LOCAL = 6,			// Teleporting in-sim without showing the progress screen
+		TELEPORT_PENDING = 7
 	};
 
 public:
@@ -556,9 +562,6 @@ class LLAgent : public LLOldEvents::LLObservable
 	// Teleport Actions
 	//--------------------------------------------------------------------
 public:
-	void 			teleportRequest(const U64& region_handle,
-									const LLVector3& pos_local,				// Go to a named location home
-									bool look_at_from_camera = false);
 	void 			teleportViaLandmark(const LLUUID& landmark_id);			// Teleport to a landmark
 	void 			teleportHome()	{ teleportViaLandmark(LLUUID::null); }	// Go home
 	void 			teleportViaLure(const LLUUID& lure_id, BOOL godlike);	// To an invited location
@@ -569,6 +572,44 @@ class LLAgent : public LLOldEvents::LLObservable
 protected:
 	bool 			teleportCore(bool is_local = false); 					// Stuff for all teleports; returns true if the teleport can proceed
 
+	//--------------------------------------------------------------------
+	// Teleport State
+	//--------------------------------------------------------------------
+
+public:
+	bool            hasRestartableFailedTeleportRequest();
+	void            restartFailedTeleportRequest();
+	void            clearTeleportRequest();
+	void            setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
+
+private:
+	friend class LLTeleportRequest;
+	friend class LLTeleportRequestViaLandmark;
+	friend class LLTeleportRequestViaLure;
+	friend class LLTeleportRequestViaLocation;
+	friend class LLTeleportRequestViaLocationLookAt;
+
+	LLTeleportRequestPtr        mTeleportRequest;
+	boost::signals2::connection mTeleportFinishedSlot;
+	boost::signals2::connection mTeleportFailedSlot;
+
+	bool            mIsMaturityRatingChangingDuringTeleport;
+	U8              mMaturityRatingChange;
+
+	bool            hasPendingTeleportRequest();
+	void            startTeleportRequest();
+
+	void 			teleportRequest(const U64& region_handle,
+									const LLVector3& pos_local,				// Go to a named location home
+									bool look_at_from_camera = false);
+	void 			doTeleportViaLandmark(const LLUUID& landmark_id);			// Teleport to a landmark
+	void 			doTeleportViaLure(const LLUUID& lure_id, BOOL godlike);	// To an invited location
+	void 			doTeleportViaLocation(const LLVector3d& pos_global);		// To a global location - this will probably need to be deprecated
+	void			doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation
+
+	void            handleTeleportFinished();
+	void            handleTeleportFailed();
+
 	//--------------------------------------------------------------------
 	// Teleport State
 	//--------------------------------------------------------------------
@@ -614,8 +655,6 @@ class LLAgent : public LLOldEvents::LLObservable
 	const LLAgentAccess& getAgentAccess();
 	BOOL			canManageEstate() const;
 	BOOL			getAdminOverride() const;
-	// ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp).
-	void 			setAOTransition();
 private:
 	LLAgentAccess * mAgentAccess;
 	
@@ -650,13 +689,28 @@ class LLAgent : public LLOldEvents::LLObservable
 	bool 			isTeen() const;
 	bool 			isMature() const;
 	bool 			isAdult() const;
-	void 			setTeen(bool teen);
 	void 			setMaturity(char text);
-	static int 		convertTextToMaturity(char text); 
-	bool 			sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"?
+	static int 		convertTextToMaturity(char text);
+
+private:
+	bool                            mIsDoSendMaturityPreferenceToServer;
+	unsigned int                    mMaturityPreferenceRequestId;
+	unsigned int                    mMaturityPreferenceResponseId;
+	unsigned int                    mMaturityPreferenceNumRetries;
+	U8                              mLastKnownRequestMaturity;
+	U8                              mLastKnownResponseMaturity;
+
+	bool            isMaturityPreferenceSyncedWithServer() const;
+	void 			sendMaturityPreferenceToServer(U8 pPreferredMaturity);
+
+	friend class LLMaturityPreferencesResponder;
+	void            handlePreferredMaturityResult(U8 pServerMaturity);
+	void            handlePreferredMaturityError();
+	void            reportPreferredMaturitySuccess();
+	void            reportPreferredMaturityError();
 
 	// Maturity callbacks for PreferredMaturity control variable
-	void 			handleMaturity(const LLSD& newvalue);
+	void 			handleMaturity(const LLSD &pNewValue);
 	bool 			validateMaturity(const LLSD& newvalue);
 
 
diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp
index 08a33ab04aef69c3a5ce4b0b2e2aa6721e8f11af..c4ee321e04f926e2f2c9b5e1f4bd2cb5ac38052f 100644
--- a/indra/newview/llagentaccess.cpp
+++ b/indra/newview/llagentaccess.cpp
@@ -33,8 +33,7 @@ LLAgentAccess::LLAgentAccess(LLControlGroup& savedSettings) :
 	mSavedSettings(savedSettings),
 	mAccess(SIM_ACCESS_PG),
 	mAdminOverride(false),
-	mGodLevel(GOD_NOT),
-	mAOTransition(false)
+	mGodLevel(GOD_NOT)
 {
 }
 
@@ -133,18 +132,6 @@ bool LLAgentAccess::isAdult() const
 	return mAccess >= SIM_ACCESS_ADULT;
 }
 
-void LLAgentAccess::setTeen(bool teen)
-{
-	if (teen)
-	{
-		mAccess = SIM_ACCESS_PG;
-	}
-	else
-	{
-		mAccess = SIM_ACCESS_MATURE;
-	}
-}
-
 //static 
 int LLAgentAccess::convertTextToMaturity(char text)
 {
@@ -182,16 +169,6 @@ void LLAgentAccess::setMaturity(char text)
 	mSavedSettings.setU32("PreferredMaturity", preferred_access);
 }
 
-void LLAgentAccess::setTransition()
-{
-	mAOTransition = true;
-}
-
-bool LLAgentAccess::isInTransition() const
-{
-	return mAOTransition;
-}
-
 bool LLAgentAccess::canSetMaturity(S32 maturity)
 {
 	if (isGodlike()) // Gods can always set their Maturity level
diff --git a/indra/newview/llagentaccess.h b/indra/newview/llagentaccess.h
index 2e98e4eea1bc06b4823f33e3176280715554be57..4e851b0aa02187fb286286b3e6f3f997283769b3 100644
--- a/indra/newview/llagentaccess.h
+++ b/indra/newview/llagentaccess.h
@@ -59,13 +59,10 @@ class LLAgentAccess
 	bool isMature() const;
 	bool isAdult() const;
 	
-	void setTeen(bool teen);
 	void setMaturity(char text);
 	
 	static int convertTextToMaturity(char text);
 	
-	void setTransition();	// sets the transition bit, which defaults to false
-	bool isInTransition() const;
 	bool canSetMaturity(S32 maturity);
 	
 private:
@@ -73,13 +70,6 @@ class LLAgentAccess
 	U8 mGodLevel;
 	bool mAdminOverride;
 	
-	// this should be deleted after the 60-day AO transition.
-	// It should be safe to remove it in Viewer 2009
-	// It's set by a special short-term flag in login.cgi 
-	// called ao_transition. When that's gone, this can go, along with
-	// all of the code that depends on it.
-	bool mAOTransition;
-	
 	LLControlGroup& mSavedSettings;
 };
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ed04b5bf383bf5bbbc640dd539c39da912f70e9c..efa24796e587a06f9b5263ac287610a09d0e50a9 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -94,6 +94,7 @@
 #include "llupdaterservice.h"
 #include "llcallfloater.h"
 #include "llfloatertexturefetchdebugger.h"
+#include "llspellcheck.h"
 
 // Linden library includes
 #include "llavatarnamecache.h"
@@ -117,6 +118,7 @@
 // Third party library includes
 #include <boost/bind.hpp>
 #include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
 
 
 
@@ -625,6 +627,7 @@ LLAppViewer::LLAppViewer() :
 	mPurgeOnExit(false),
 	mSecondInstance(false),
 	mSavedFinalSnapshot(false),
+	mSavePerAccountSettings(false),		// don't save settings on logout unless login succeeded.
 	mForceGraphicsDetail(false),
 	mQuitRequested(false),
 	mLogoutRequestSent(false),
@@ -1162,6 +1165,8 @@ void LLAppViewer::checkMemory()
 
 static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
 static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep");
+static LLFastTimer::DeclareTimer FTM_YIELD("Yield");
+
 static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache");
 static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode");
 static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread");
@@ -1347,6 +1352,7 @@ bool LLAppViewer::mainLoop()
 				// yield some time to the os based on command line option
 				if(mYieldTime >= 0)
 				{
+					LLFastTimer t(FTM_YIELD);
 					ms_sleep(mYieldTime);
 				}
 
@@ -1796,6 +1802,13 @@ bool LLAppViewer::cleanup()
 	{
 		llinfos << "Not saving per-account settings; don't know the account name yet." << llendl;
 	}
+	// Only save per account settings if the previous login succeeded, otherwise
+	// we might end up with a cleared out settings file in case a previous login
+	// failed after loading per account settings.
+	else if (!mSavePerAccountSettings)
+	{
+		llinfos << "Not saving per-account settings; last login was not successful." << llendl;
+	}
 	else
 	{
 		gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
@@ -2550,6 +2563,19 @@ bool LLAppViewer::initConfiguration()
 		//gDirUtilp->setSkinFolder("default");
     }
 
+	if (gSavedSettings.getBOOL("SpellCheck"))
+	{
+		std::list<std::string> dict_list;
+		std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+		boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+		if (!dict_list.empty())
+		{
+			LLSpellChecker::setUseSpellCheck(dict_list.front());
+			dict_list.pop_front();
+			LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+		}
+	}
+
     mYieldTime = gSavedSettings.getS32("YieldTime");
 
 	// Read skin/branding settings if specified.
@@ -5009,6 +5035,10 @@ void LLAppViewer::handleLoginComplete()
 	mOnLoginCompleted();
 
 	writeDebugInfo();
+
+	// we logged in successfully, so save settings on logout
+	llinfos << "Login successful, per account settings will be saved on log out." << llendl;
+	mSavePerAccountSettings=true;
 }
 
 void LLAppViewer::launchUpdater()
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index f7d019ccbacfd5ba235832687f32a243f21d62b0..ae3c795d1e2d9ced65bc77cfd79072a2b33adbab 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -247,6 +247,7 @@ class LLAppViewer : public LLApp
     bool mPurgeOnExit;
 
 	bool mSavedFinalSnapshot;
+	bool mSavePerAccountSettings;		// only save per account settings if login succeeded
 
 	bool mForceGraphicsDetail;
 
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f1ce2bcd060d3a3d115203bb7aecec1a5fb43ee
--- /dev/null
+++ b/indra/newview/llautoreplace.cpp
@@ -0,0 +1,771 @@
+/**
+ * @file llautoreplace.cpp
+ * @brief Auto Replace Manager
+ *
+ * $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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llautoreplace.h"
+#include "llsdserialize.h"
+#include "llboost.h"
+#include "llcontrol.h"
+#include "llviewercontrol.h"
+#include "llnotificationsutil.h"
+
+LLAutoReplace* LLAutoReplace::sInstance;
+
+const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
+
+LLAutoReplace::LLAutoReplace()
+{
+}
+
+LLAutoReplace::~LLAutoReplace()
+{
+	sInstance = NULL;
+}
+
+void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
+{
+	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
+	if(perform_autoreplace)
+	{
+		S32 wordEnd = cursorPos-1;
+		LLWString text = inputText.getWString();
+
+		bool atSpace  = (text[wordEnd] == ' ');
+		bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+
+		if (atSpace || haveWord)
+		{
+			if (atSpace && wordEnd > 0)
+			{
+				// find out if this space immediately follows a word
+				wordEnd--;
+				haveWord  = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+			}
+			if (haveWord)
+			{
+				// wordEnd points to the end of a word, now find the start of the word
+				std::string word;
+				S32 wordStart = wordEnd;
+				for ( S32 backOne = wordStart - 1;
+					  backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]);
+					  backOne--
+					 )
+				{
+					wordStart--; // walk wordStart back to the beginning of the word
+				}
+				LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
+				std::string strText  = std::string(text.begin(), text.end());
+				std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
+				std::string replacementWord( mSettings.replaceWord( lastWord ) );
+
+				if ( replacementWord != lastWord )
+				{
+					// The last word is one for which we have a replacement
+					if (atSpace)
+					{
+						// replace the last word in the input
+						LLWString strNew = utf8str_to_wstring(replacementWord);
+						LLWString strOld = utf8str_to_wstring(lastWord);
+						int size_change = strNew.size() - strOld.size();
+
+						text.replace(wordStart,lastWord.length(),strNew);
+						inputText = wstring_to_utf8str(text);
+						cursorPos+=size_change;
+					}
+				}
+			}
+		}
+	}
+}
+
+LLAutoReplace* LLAutoReplace::getInstance()
+{
+	if(!sInstance)
+	{
+		sInstance = new LLAutoReplace();
+		sInstance->loadFromSettings();
+	}
+	return sInstance;
+}
+
+std::string LLAutoReplace::getUserSettingsFileName()
+{
+	std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+
+	if (!path.empty())
+	{
+		path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, SETTINGS_FILE_NAME);
+	}
+	return path;
+}
+
+std::string LLAutoReplace::getAppSettingsFileName()
+{
+	std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "");
+
+	if (!path.empty())
+	{
+		path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, SETTINGS_FILE_NAME);
+	}
+	else
+	{
+		LL_ERRS("AutoReplace") << "Failed to get app settings directory name" << LL_ENDL;
+	}
+	return path;
+}
+
+LLAutoReplaceSettings LLAutoReplace::getSettings()
+{
+	return mSettings;
+}
+
+void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings)
+{
+	mSettings.set(newSettings);
+	/// Make the newSettings active and write them to user storage
+	saveToUserSettings();
+}
+
+void LLAutoReplace::loadFromSettings()
+{
+	std::string filename=getUserSettingsFileName();
+	if (filename.empty())
+	{
+		LL_INFOS("AutoReplace") << "no valid user settings directory." << LL_ENDL;
+	}
+	if(gDirUtilp->fileExists(filename))
+	{
+		LLSD userSettings;
+		llifstream file;
+		file.open(filename.c_str());
+		if (file.is_open())
+		{
+			LLSDSerialize::fromXML(userSettings, file);
+		}
+		file.close();
+		if ( mSettings.setFromLLSD(userSettings) )
+		{
+			LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL;
+		}
+		else
+		{
+			LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL;
+		}
+	}
+	else // no user settings found, try application settings
+	{
+		std::string defaultName = getAppSettingsFileName();
+		LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found"<< LL_ENDL;
+
+		bool gotSettings = false;
+		if(gDirUtilp->fileExists(defaultName))
+		{
+			LLSD appDefault;
+			llifstream file;
+			file.open(defaultName.c_str());
+			if (file.is_open())
+			{
+				LLSDSerialize::fromXMLDocument(appDefault, file);
+			}
+			file.close();
+
+			if ( mSettings.setFromLLSD(appDefault) )
+			{
+				LL_INFOS("AutoReplace") << "settings loaded from '" << defaultName.c_str() << "'" << LL_ENDL;
+				gotSettings = true;
+			}
+			else
+			{
+				LL_WARNS("AutoReplace") << "invalid settings found in '" << defaultName.c_str() << "'" << LL_ENDL;
+			}
+		}
+		
+		if ( ! gotSettings )
+		{
+			if (mSettings.setFromLLSD(mSettings.getExampleLLSD()))
+			{
+				LL_WARNS("AutoReplace") << "no settings found; loaded example." << LL_ENDL;
+			}
+			else
+			{
+				LL_WARNS("AutoReplace") << "no settings found and example invalid!" << LL_ENDL;
+			}
+		}
+	}
+}
+
+void LLAutoReplace::saveToUserSettings()
+{
+	std::string filename=getUserSettingsFileName();
+	llofstream file;
+	file.open(filename.c_str());
+	LLSDSerialize::toPrettyXML(mSettings.getAsLLSD(), file);
+	file.close();
+	LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL;
+}
+
+// ================================================================
+// LLAutoReplaceSettings
+// ================================================================
+
+const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_NAME         = "name";    	 ///< key for looking up list names
+const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_REPLACEMENTS = "replacements"; ///< key for looking up replacement map
+
+LLAutoReplaceSettings::LLAutoReplaceSettings()
+{
+}
+
+LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settings)
+{
+	// copy all values through fundamental type intermediates for thread safety
+	mLists = LLSD::emptyArray();
+
+	for ( LLSD::array_const_iterator list = settings.mLists.beginArray(), listEnd = settings.mLists.endArray();
+		  list != listEnd;
+		  list++
+		 )
+	{
+		if ( (*list).isMap() ) // can fail due to LLSD-30: ignore it
+		{
+			LLSD listMap = LLSD::emptyMap();
+			std::string listName = (*list)[AUTOREPLACE_LIST_NAME];
+			listMap[AUTOREPLACE_LIST_NAME] = listName;
+			listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+
+			for ( LLSD::map_const_iterator
+					  entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(),
+					  entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap();
+				  entry != entriesEnd;
+				  entry++
+				 )
+			{
+				std::string keyword = entry->first;
+				std::string replacement = entry->second.asString();
+				listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement));
+			}
+
+			mLists.append(listMap);
+		}
+	}
+}
+
+void LLAutoReplaceSettings::set(const LLAutoReplaceSettings& newSettings)
+{
+	mLists = newSettings.mLists;
+}
+
+bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD)
+{
+	bool settingsValid = true;
+
+	if ( settingsFromLLSD.isArray() )
+	{
+		for ( LLSD::array_const_iterator
+				  list = settingsFromLLSD.beginArray(),
+				  listEnd = settingsFromLLSD.endArray();
+			  settingsValid && list != listEnd;
+			  list++
+			 )
+		{
+			if ( (*list).isDefined() ) // can be undef due to LLSD-30: ignore it
+			{
+				settingsValid = listIsValid(*list);
+			}
+		}
+	}
+	else
+	{
+		settingsValid = false;
+		LL_WARNS("AutoReplace") << "settings are not an array" << LL_ENDL;
+	}
+
+	if ( settingsValid )
+	{
+		mLists = settingsFromLLSD;
+	}
+	else
+	{
+		LL_WARNS("AutoReplace") << "invalid settings discarded; using hard coded example" << LL_ENDL;
+	}
+
+	return settingsValid;
+}
+
+bool LLAutoReplaceSettings::listNameMatches( const LLSD& list, const std::string name )
+{
+	return list.isMap()
+		&& list.has(AUTOREPLACE_LIST_NAME)
+		&& list[AUTOREPLACE_LIST_NAME].asString() == name;
+}
+
+const LLSD* LLAutoReplaceSettings::getListEntries(std::string listName)
+{
+	const LLSD* returnedEntries = NULL;
+	for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray();
+		 returnedEntries == NULL && list != endList;
+		 list++
+		)
+	{
+		const LLSD& thisList = *list;
+		if ( listNameMatches(thisList, listName) )
+		{
+			returnedEntries = &thisList[AUTOREPLACE_LIST_REPLACEMENTS];
+		}
+	}
+	return returnedEntries;
+}
+
+std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::string listName)
+{
+	std::string replacement;
+	bool foundList = false;
+	for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray();
+		 ! foundList && list != endList;
+		 list++
+		)
+	{
+		const LLSD& thisList = *list;
+		if ( listNameMatches(thisList, listName) )
+		{
+			foundList = true; // whether there is a replacement or not, we're done
+			if (   thisList.isMap()
+				&& thisList.has(AUTOREPLACE_LIST_REPLACEMENTS)
+				&& thisList[AUTOREPLACE_LIST_REPLACEMENTS].has(keyword)
+				)
+			{
+				replacement = thisList[AUTOREPLACE_LIST_REPLACEMENTS][keyword].asString();
+				LL_DEBUGS("AutoReplace")<<"'"<<keyword<<"' -> '"<<replacement<<"'"<<LL_ENDL;
+			}
+		}
+		if (!foundList)
+		{
+			LL_WARNS("AutoReplace")<<"failed to find list '"<<listName<<"'"<<LL_ENDL;
+		}
+	}
+	if (replacement.empty())
+	{
+		LL_WARNS("AutoReplace")<<"failed to find '"<<keyword<<"'"<<LL_ENDL;
+	}
+	return replacement;
+}
+
+LLSD LLAutoReplaceSettings::getListNames()
+{
+	LL_DEBUGS("AutoReplace")<<"====="<<LL_ENDL;
+	LLSD toReturn = LLSD::emptyArray();
+	S32 counter=0;
+	for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray();
+		 list != endList;
+		 list++
+		)
+	{
+		const LLSD& thisList = *list;
+		if ( thisList.isMap() )
+		{
+			if ( thisList.has(AUTOREPLACE_LIST_NAME) )
+			{
+				std::string name = thisList[AUTOREPLACE_LIST_NAME].asString();
+				LL_DEBUGS("AutoReplace")<<counter<<" '"<<name<<"'"<<LL_ENDL;
+				toReturn.append(LLSD(name));
+			}
+			else
+			{
+				LL_ERRS("AutoReplace") <<counter<<" ! MISSING "<<AUTOREPLACE_LIST_NAME<< LL_ENDL;
+			}
+		}
+		else
+		{
+			LL_WARNS("AutoReplace")<<counter<<" ! not a map: "<<LLSD::typeString(thisList.type())<< LL_ENDL;
+		}
+		counter++;
+	}
+	LL_DEBUGS("AutoReplace")<<"^^^^^^"<<LL_ENDL;
+	return toReturn;
+}
+
+bool LLAutoReplaceSettings::listIsValid(const LLSD& list)
+{
+	bool listValid = true;
+	if ( ! list.isMap() )
+	{
+		listValid = false;
+		LL_WARNS("AutoReplace") << "list is not a map" << LL_ENDL;
+	}
+	else if (   ! list.has(AUTOREPLACE_LIST_NAME)
+			 || ! list[AUTOREPLACE_LIST_NAME].isString()
+			 || list[AUTOREPLACE_LIST_NAME].asString().empty()
+			 )
+	{
+		listValid = false;
+		LL_WARNS("AutoReplace")
+			<< "list found without " << AUTOREPLACE_LIST_NAME
+			<< " (or it is empty)"
+			<< LL_ENDL;
+	}
+	else if ( ! list.has(AUTOREPLACE_LIST_REPLACEMENTS) || ! list[AUTOREPLACE_LIST_REPLACEMENTS].isMap() )
+	{
+		listValid = false;
+		LL_WARNS("AutoReplace") << "list '" << list[AUTOREPLACE_LIST_NAME].asString() << "' without " << AUTOREPLACE_LIST_REPLACEMENTS << LL_ENDL;
+	}
+	else
+	{
+		for ( LLSD::map_const_iterator
+				  entry = list[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(),
+				  entriesEnd = list[AUTOREPLACE_LIST_REPLACEMENTS].endMap();
+			  listValid && entry != entriesEnd;
+			  entry++
+			 )
+		{
+			if ( ! entry->second.isString() )
+			{
+				listValid = false;
+				LL_WARNS("AutoReplace")
+					<< "non-string replacement value found in list '"
+					<< list[AUTOREPLACE_LIST_NAME].asString() << "'"
+					<< LL_ENDL;
+			}
+		}
+	}
+
+	return listValid;
+}
+
+const LLSD* LLAutoReplaceSettings::exportList(std::string listName)
+{
+	const LLSD* exportedList = NULL;
+	for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray();
+		  exportedList == NULL && list != listEnd;
+		  list++
+		 )
+	{
+		if ( listNameMatches(*list, listName) )
+		{
+			const LLSD& namedList = (*list);
+			exportedList = &namedList;
+		}
+	}
+	return exportedList;
+}
+
+bool LLAutoReplaceSettings::listNameIsUnique(const LLSD& newList)
+{
+	bool nameIsUnique = true;
+	// this must always be called with a valid list, so it is safe to assume it has a name
+	std::string newListName = newList[AUTOREPLACE_LIST_NAME].asString();
+	for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray();
+		  nameIsUnique && list != listEnd;
+		  list++
+		 )
+	{
+		if ( listNameMatches(*list, newListName) )
+		{
+			LL_WARNS("AutoReplace")<<"duplicate list name '"<<newListName<<"'"<<LL_ENDL;
+			nameIsUnique = false;
+		}
+	}
+	return nameIsUnique;
+}
+
+/* static */
+void LLAutoReplaceSettings::createEmptyList(LLSD& emptyList)
+{
+	emptyList = LLSD::emptyMap();
+	emptyList[AUTOREPLACE_LIST_NAME] = "Empty";
+	emptyList[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+}
+
+/* static */
+void LLAutoReplaceSettings::setListName(LLSD& list, const std::string& newName)
+{
+	list[AUTOREPLACE_LIST_NAME] = newName;
+}
+
+/* static */
+std::string LLAutoReplaceSettings::getListName(LLSD& list)
+{
+	std::string name;
+	if ( list.isMap() && list.has(AUTOREPLACE_LIST_NAME) && list[AUTOREPLACE_LIST_NAME].isString() )
+	{
+		name = list[AUTOREPLACE_LIST_NAME].asString();
+	}
+	return name;
+}
+
+LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::addList(const LLSD& newList)
+{
+	AddListResult result;
+	if ( listIsValid( newList ) )
+	{
+		if ( listNameIsUnique( newList ) )
+		{
+			mLists.append(newList);
+			result = AddListOk;
+		}
+		else
+		{
+			LL_WARNS("AutoReplace") << "attempt to add duplicate name" << LL_ENDL;
+			result = AddListDuplicateName;
+		}
+	}
+	else
+	{
+		LL_WARNS("AutoReplace") << "attempt to add invalid list" << LL_ENDL;
+		result = AddListInvalidList;
+	}
+	return result;
+}
+
+bool LLAutoReplaceSettings::removeReplacementList(std::string listName)
+{
+	bool found = false;
+	for( S32 index = 0; !found && mLists[index].isDefined(); index++ )
+	{
+		if( listNameMatches(mLists.get(index), listName) )
+		{
+			LL_DEBUGS("AutoReplace")<<"list '"<<listName<<"'"<<LL_ENDL;
+			mLists.erase(index);
+			found = true;
+		}
+	}
+	return found;
+}
+
+/// Move the named list up in the priority order
+bool LLAutoReplaceSettings::increaseListPriority(std::string listName)
+{
+	LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL;
+	bool found = false;
+	S32 search_index, previous_index;
+	LLSD targetList;
+	// The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30
+	previous_index = -1;
+	for ( search_index = 0, targetList = mLists[0];
+		  !found && search_index < mLists.size();
+		  search_index += 1, targetList = mLists[search_index]
+		 )
+	{
+		if ( targetList.isMap() )
+		{
+			if ( listNameMatches( targetList, listName) )
+			{
+				LL_DEBUGS("AutoReplace")<<"found at "<<search_index<<", previous is "<<previous_index<<LL_ENDL;
+				found = true;
+				if (previous_index >= 0)
+				{
+					LL_DEBUGS("AutoReplace") << "erase "<<search_index<<LL_ENDL;
+					mLists.erase(search_index);
+					LL_DEBUGS("AutoReplace") << "insert at "<<previous_index<<LL_ENDL;
+					mLists.insert(previous_index, targetList);
+				} 
+				else
+				{
+					LL_WARNS("AutoReplace") << "attempted to move top list up" << LL_ENDL;
+				}
+			}
+			else
+			{
+				previous_index = search_index;
+			}
+		}
+		else
+		{
+			LL_DEBUGS("AutoReplace") << search_index<<" is "<<LLSD::typeString(targetList.type())<<LL_ENDL;
+		}		
+	}
+	return found;
+}
+
+/// Move the named list down in the priority order
+bool LLAutoReplaceSettings::decreaseListPriority(std::string listName)
+{
+	LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL;
+	S32 found_index = -1;	
+	S32 search_index;
+	for ( search_index = 0;
+		  found_index == -1 && search_index < mLists.size();
+		  search_index++
+		 )
+	{
+		if ( listNameMatches( mLists[search_index], listName) )
+		{
+			LL_DEBUGS("AutoReplace")<<"found at index "<<search_index<<LL_ENDL;
+			found_index = search_index;
+		}
+	}
+	if (found_index != -1)
+	{
+		S32 next_index;
+		for ( next_index = found_index+1;
+			  next_index < mLists.size() && ! mLists[next_index].isMap();
+			  next_index++
+			 )
+		{
+			// skipping over any undefined slots (see LLSD-30)
+			LL_WARNS("AutoReplace")<<next_index<<" ! not a map: "<<LLSD::typeString(mLists[next_index].type())<< LL_ENDL;
+		}
+		if ( next_index < mLists.size() )
+		{
+			LLSD next_list = mLists[next_index];
+			LL_DEBUGS("AutoReplace") << "erase "<<next_index<<LL_ENDL;
+			mLists.erase(next_index);
+			LL_DEBUGS("AutoReplace") << "insert at "<<found_index<<LL_ENDL;
+			mLists.insert(found_index, next_list);
+		}
+		else
+		{
+			LL_WARNS("AutoReplace") << "attempted to move bottom list down" << LL_ENDL;
+		}
+	}
+	else
+	{
+		LL_WARNS("AutoReplace") << "not found" << LL_ENDL;
+	}
+	return (found_index != -1);
+}
+
+
+std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord)
+{
+	std::string returnedWord = currentWord; // in case no replacement is found
+	static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace");
+	if ( autoreplace_enabled )
+	{
+		LL_DEBUGS("AutoReplace")<<"checking '"<<currentWord<<"'"<< LL_ENDL;
+		//loop through lists in order
+		bool found = false;
+		for( LLSD::array_const_iterator list = mLists.beginArray(), endLists = mLists.endArray();
+			 ! found && list != endLists;
+			 list++
+			)
+		{
+			const LLSD& checkList = *list;
+			const LLSD& replacements = checkList[AUTOREPLACE_LIST_REPLACEMENTS];
+
+			if ( replacements.has(currentWord) )
+			{
+				found = true;
+				LL_DEBUGS("AutoReplace")
+					<< "  found in list '" << checkList[AUTOREPLACE_LIST_NAME].asString()
+					<< " => '" << replacements[currentWord].asString() << "'"
+					<< LL_ENDL;
+				returnedWord = replacements[currentWord].asString();
+			}
+		}
+	}
+	return returnedWord;
+}
+
+bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName)
+{
+	bool added = false;
+
+	if ( ! keyword.empty() && ! replacement.empty() )
+	{
+		bool isOneWord = true;
+		for (S32 character = 0; isOneWord && character < keyword.size(); character++ )
+		{
+			if ( ! LLWStringUtil::isPartOfWord(keyword[character]) )
+			{
+				LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "<<keyword.size()<<" '"<<character<<"')" << LL_ENDL;
+				isOneWord = false;
+			}
+		}
+
+		if ( isOneWord )
+		{
+			bool listFound = false;
+			for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray();
+				 ! listFound && list != endLists;
+				 list++
+				)
+			{
+				if ( listNameMatches(*list, listName) )
+				{
+					listFound = true;
+					(*list)[AUTOREPLACE_LIST_REPLACEMENTS][wstring_to_utf8str(keyword)]=wstring_to_utf8str(replacement);
+				}
+			}
+			if (listFound)
+			{
+				added = true;
+			}
+			else
+			{
+				LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL;
+			}
+		}
+	}
+
+	return added;
+}
+
+bool LLAutoReplaceSettings::removeEntryFromList(std::string keyword, std::string listName)
+{
+	bool found = false;
+	for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray();
+		 ! found && list != endLists;
+		 list++
+		)
+	{
+		if ( listNameMatches(*list, listName) )
+		{
+			found = true;
+			(*list)[AUTOREPLACE_LIST_REPLACEMENTS].erase(keyword);
+		}
+	}
+	if (!found)
+	{
+		LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL;
+	}
+	return found;
+}
+
+LLSD LLAutoReplaceSettings::getExampleLLSD()
+{
+	LL_DEBUGS("AutoReplace")<<LL_ENDL;
+	LLSD example = LLSD::emptyArray();
+
+	example[0] = LLSD::emptyMap();
+	example[0][AUTOREPLACE_LIST_NAME]    = "Example List 1";
+	example[0][AUTOREPLACE_LIST_REPLACEMENTS]    = LLSD::emptyMap();
+	example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword1"] = "replacement string 1";
+	example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword2"] = "replacement string 2";
+
+	example[1] = LLSD::emptyMap();
+	example[1][AUTOREPLACE_LIST_NAME]    = "Example List 2";
+	example[1][AUTOREPLACE_LIST_REPLACEMENTS]    = LLSD::emptyMap();
+	example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake1"] = "correction 1";
+	example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake2"] = "correction 2";
+
+	return example;
+}
+
+const LLSD& LLAutoReplaceSettings::getAsLLSD()
+{
+	return mLists;
+}
+
+LLAutoReplaceSettings::~LLAutoReplaceSettings()
+{
+}
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
new file mode 100644
index 0000000000000000000000000000000000000000..30b1fd2c659e604a8564bc9af3e12c6f7ad67d55
--- /dev/null
+++ b/indra/newview/llautoreplace.h
@@ -0,0 +1,228 @@
+/** 
+ * @file llautoreplace.h
+ * @brief Auto Replace Manager
+ * $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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * 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
+ */
+#ifndef LLAUTOREPLACE_H
+#define LLAUTOREPLACE_H
+
+#include "lllineeditor.h"
+
+class LLAutoReplace;
+
+/** The configuration data for the LLAutoReplace object
+ *
+ * This is a separate class so that the LLFloaterAutoReplaceSettings
+ * can have a copy of the configuration to manipulate before committing
+ * the changes back to the LLAutoReplace singleton that provides the 
+ * autoreplace callback.
+ */
+class LLAutoReplaceSettings
+{
+  public:
+	LLAutoReplaceSettings();
+	~LLAutoReplaceSettings();
+
+	/// Constructor for creating a tempory copy of the current settings
+	LLAutoReplaceSettings(const LLAutoReplaceSettings& settings);
+
+	/// Replace the current settings with new ones and save them to the user settings file
+	void set(const LLAutoReplaceSettings& newSettings);
+	
+	/// Load the current settings read from an LLSD file
+	bool setFromLLSD(const LLSD& settingsFromLLSD);
+	///< @returns whether or not the settingsFromLLSD were valid
+	
+	// ================================================================
+	///@{ @name List Operations
+	// ================================================================
+
+	/// @returns the configured list names as an LLSD Array of strings
+	LLSD getListNames();
+
+	/// Status values returned from the addList method
+	typedef enum
+	{
+		AddListOk,
+		AddListDuplicateName,
+		AddListInvalidList,
+	} AddListResult;
+	
+	/// Inserts a new list at the end of the priority order
+	AddListResult addList(const LLSD& newList);
+
+	/// Removes the named list, @returns false if not found
+	bool removeReplacementList(std::string listName);
+
+	/// Move the named list up in the priority order 
+	bool increaseListPriority(std::string listName);
+	///< @returns false if the list is not found
+
+	/// Move the named list down in the priority order 
+	bool decreaseListPriority(std::string listName);
+	///< @returns false if the list is not found
+
+	/// Get a copy of just one list (for saving to an export file)
+	const LLSD* exportList(std::string listName);
+	/// @returns an LLSD map 
+
+	/// Checks for required elements, and that each has the correct type.
+	bool listIsValid(const LLSD& listSettings);
+	
+	/// Checks for required elements, and that each has the correct type.
+	bool listNameIs(const LLSD& listSettings);
+	
+	/// Checks to see if a new lists name conflicts with one in the settings
+	bool listNameIsUnique(const LLSD& newList);
+	/// @note must be called with LLSD that has passed listIsValid
+	
+	/// Initializes emptyList to an empty list named 'Empty'
+	static void createEmptyList(LLSD& emptyList);
+
+	/// Resets the name of a list to a new value
+	static void setListName(LLSD& list, const std::string& newName);
+
+	/// Gets the name of a list
+	static std::string getListName(LLSD& list);
+
+    ///@}
+	// ================================================================
+	///@{ @name Replacement Entry Operations
+	// ================================================================
+	
+	/// Get the replacements specified by a given list
+	const LLSD* getListEntries(std::string listName);
+	///< @returns an LLSD Map of keyword -> replacement test pairs
+
+	/// Get the replacement for the keyword from the specified list
+	std::string replacementFor(std::string keyword, std::string listName);
+	
+	/// Adds a keywword/replacement pair to the named list
+	bool addEntryToList(LLWString keyword, LLWString replacement, std::string listName);
+
+	/// Removes the keywword and its replacement from the named list
+	bool removeEntryFromList(std::string keyword, std::string listName);
+
+	/** 
+	 * Look for currentWord in the lists in order, returning any substitution found
+	 * If no configured substitution is found, returns currentWord
+	 */
+	std::string replaceWord(const std::string currentWord /**< word to search for */ );
+
+	/// Provides a hard-coded example of settings 
+	LLSD getExampleLLSD();
+
+	/// Get the actual settings as LLSD
+	const LLSD& getAsLLSD();
+	///< @note for use only in AutoReplace::saveToUserSettings
+	
+  private:
+	/// Efficiently and safely compare list names 
+	bool listNameMatches( const LLSD& list, const std::string name );
+
+	/// The actual llsd data structure
+	LLSD mLists;
+
+	static const std::string AUTOREPLACE_LIST_NAME;    	 ///< key for looking up list names
+	static const std::string AUTOREPLACE_LIST_REPLACEMENTS; ///< key for looking up replacement map
+	
+    /**<
+	 * LLSD structure of the lists
+	 * - The configuration is an array (mLists),
+	 * - Each entry in the array is a replacement list
+	 * - Each replacement list is a map with three keys:
+	 * @verbatim  
+	 *     "name"    	  String    the name of the list
+	 *     "replacements" Map       keyword -> replacement pairs
+	 * 
+	 * <llsd>
+	 *   <array> 
+	 *     <map>
+	 *       <key>name</key>    <string>List 1</string>
+	 *       <key>data</key>
+	 *         <map>
+	 *           <key>keyword1</key>  <string>replacement1</string>
+	 *           <key>keyword2</key>  <string>replacement2</string>
+	 *    	   </map>
+	 *     </map> 
+	 *     <map>
+	 *       <key>name</key>    <string>List 2</string>
+	 *       <key>data</key>
+	 *         <map>
+	 *           <key>keyword1</key>  <string>replacement1</string>
+	 *           <key>keyword2</key>  <string>replacement2</string>
+	 *    	   </map>
+	 *     </map>
+	 *   </array> 
+	 * </llsd>
+	 * @endverbatim
+	 */
+};
+
+/** Provides a facility to auto-replace text dynamically as it is entered.
+ *
+ * When the end of a word is detected (defined as any punctuation character,
+ * or any whitespace except newline or return), the preceding word is used
+ * as a lookup key in an ordered list of maps.  If a match is found in any
+ * map, the keyword is replaced by the associated value from the map.
+ *
+ * See the autoreplaceCallback method for how to add autoreplace functionality
+ * to a text entry tool.
+ */
+class LLAutoReplace : public LLSingleton<LLAutoReplace>
+{
+  public:
+	LLAutoReplace();
+	~LLAutoReplace();
+
+	/// @return a pointer to the active instance
+	static LLAutoReplace* getInstance();
+
+	/// Callback that provides the hook for use in text entry methods
+	void autoreplaceCallback(LLUIString& inputText, S32& cursorPos);
+
+	/// Get a copy of the current settings
+	LLAutoReplaceSettings getSettings();
+
+	/// Commit new settings after making changes
+	void setSettings(const LLAutoReplaceSettings& settings);
+
+  private:
+	friend class LLSingleton<LLAutoReplace>;
+	static LLAutoReplace* sInstance; ///< the active settings instance
+
+	LLAutoReplaceSettings mSettings; ///< configuration information
+	
+	/// Read settings from persistent storage
+	void loadFromSettings();
+
+	/// Make the newSettings active and write them to user storage
+	void saveToUserSettings();
+
+	/// Compute the user settings file name
+	std::string getUserSettingsFileName();
+
+	/// Compute the (read-ony) application settings file name
+	std::string getAppSettingsFileName();
+
+	/// basename for the settings files
+	static const char* SETTINGS_FILE_NAME;
+};
+
+#endif /* LLAUTOREPLACE_H */
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index f530d10ddc525aec066d78a1550f9824035d2940..84e73e96fa01213c6405d11859c31f4d5deada34 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -495,7 +495,7 @@ class LLChatHistoryHeader: public LLPanel
 
 	void showInfoCtrl()
 	{
-		if (mAvatarID.isNull() || mFrom.empty() || SYSTEM_FROM == mFrom) return;
+		if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return;
 				
 		if (!sInfoCtrl)
 		{
@@ -689,8 +689,11 @@ void LLChatHistory::clear()
 	mLastFromID = LLUUID::null;
 }
 
+static LLFastTimer::DeclareTimer FTM_APPEND_MESSAGE("Append Chat Message");
+
 void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params)
 {
+	LLFastTimer _(FTM_APPEND_MESSAGE);
 	bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();
 
 	llassert(mEditor);
@@ -783,7 +786,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			timestamp_style.color(timestamp_color);
 			timestamp_style.readonly_color(timestamp_color);
 		}
-		mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);
+		mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getLength() != 0, timestamp_style);
 
 		if (utf8str_trim(chat.mFromName).size() != 0)
 		{
@@ -842,7 +845,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		else
 		{
 			view = getHeader(chat, style_params, args);
-			if (mEditor->getText().size() == 0)
+			if (mEditor->getLength() == 0)
 				p.top_pad = 0;
 			else
 				p.top_pad = mTopHeaderPad;
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 21b21c152a6b981f929e21784da6c36b0db839a3..98246162f08982b279d82800515b901921554455 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -450,7 +450,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
 {
 	if (isState(ACTIVE))
 	{
-		clearState(ACTIVE);
+		clearState(ACTIVE | ANIMATED_CHILD);
 
 		if (mParent.notNull() && mParent->isActive() && warning_enabled)
 		{
@@ -538,9 +538,9 @@ F32 LLDrawable::updateXform(BOOL undamped)
 			target_rot = new_rot;
 			target_scale = new_scale;
 		}
-		else
+		else if (mVObjp->getAngularVelocity().isExactlyZero())
 		{
-			// snap to final position
+			// snap to final position (only if no target omega is applied)
 			dist_squared = 0.0f;
 			if (getVOVolume() && !isRoot())
 			{ //child prim snapping to some position, needs a rebuild
@@ -549,15 +549,25 @@ F32 LLDrawable::updateXform(BOOL undamped)
 		}
 	}
 
-	if ((mCurrentScale != target_scale) ||
-		(!isRoot() && 
-		 (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED || 
-		 !mVObjp->getAngularVelocity().isExactlyZero() ||
-		 target_pos != mXform.getPosition() ||
-		 target_rot != mXform.getRotation())))
-	{ //child prim moving or scale change requires immediate rebuild
+	LLVector3 vec = mCurrentScale-target_scale;
+	
+	if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
+	{ //scale change requires immediate rebuild
+		mCurrentScale = target_scale;
 		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
 	}
+	else if (!isRoot() && 
+		 (!mVObjp->getAngularVelocity().isExactlyZero() ||
+			dist_squared > 0.f))
+	{ //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild
+		dist_squared = 1.f; //keep this object on the move list
+		if (!isState(LLDrawable::ANIMATED_CHILD))
+		{			
+			setState(LLDrawable::ANIMATED_CHILD);
+			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
+			mVObjp->dirtySpatialGroup();
+		}
+	}
 	else if (!getVOVolume() && !isAvatar())
 	{
 		movePartition();
@@ -568,9 +578,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
 	mXform.setRotation(target_rot);
 	mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
 	mXform.updateMatrix();
-	
-	mCurrentScale = target_scale;
-	
+
 	if (mSpatialBridge)
 	{
 		gPipeline.markMoved(mSpatialBridge, FALSE);
@@ -596,7 +604,11 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)
 	// Update the face centers.
 	for (S32 i = 0; i < getNumFaces(); i++)
 	{
-		getFace(i)->updateCenterAgent();
+		LLFace* face = getFace(i);
+		if (face)
+		{
+			face->updateCenterAgent();
+		}
 	}
 }
 
@@ -651,7 +663,6 @@ BOOL LLDrawable::updateMoveUndamped()
 	}
 
 	mVObjp->clearChanged(LLXform::MOVED);
-	
 	return TRUE;
 }
 
@@ -727,7 +738,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
 				for (S32 i = 0; i < getNumFaces(); i++)
 				{
 					LLFace* facep = getFace(i);
-					if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
+					if (facep && 
+						(force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
 					{
 						LLVector4a box;
 						box.setSub(facep->mExtents[1], facep->mExtents[0]);
@@ -826,13 +838,16 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
 		for (S32 i = 0; i < getNumFaces(); i++)
 		{
 			LLFace *facep = getFace(i);
-			facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
-			facep->mExtents[0].add(shift_vector);
-			facep->mExtents[1].add(shift_vector);
-			
-			if (!volume && facep->hasGeometry())
+			if (facep)
 			{
-				facep->clearVertexBuffer();
+				facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
+				facep->mExtents[0].add(shift_vector);
+				facep->mExtents[1].add(shift_vector);
+			
+				if (!volume && facep->hasGeometry())
+				{
+					facep->clearVertexBuffer();
+				}
 			}
 		}
 		
@@ -954,7 +969,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
 		for (S32 i = 0; i < getNumFaces(); ++i)
 		{
 			LLFace* facep = getFace(i);
-			facep->clearVertexBuffer();
+			if (facep)
+			{
+				facep->clearVertexBuffer();
+			}
 		}
 	}
 
@@ -1529,10 +1547,10 @@ BOOL LLDrawable::isAnimating() const
 		return TRUE;
 	}
 
-	if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
-	{
+	/*if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
+	{ //target omega
 		return TRUE;
-	}
+	}*/
 
 	return FALSE;
 }
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index e268640a21cdf806415bd68bea90e9f719da88df..e2064b79f875037881b9b3ffdfa5611f7e74d3e8 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -277,6 +277,7 @@ class LLDrawable : public LLRefCount
 		HAS_ALPHA		= 0x04000000,
 		RIGGED			= 0x08000000,
 		PARTITION_MOVE	= 0x10000000,
+		ANIMATED_CHILD  = 0x20000000,
 	} EDrawableFlags;
 
 private: //aligned members
@@ -333,12 +334,14 @@ inline LLFace* LLDrawable::getFace(const S32 i) const
 
 	if ((U32) i >= mFaces.size())
 	{
-		llerrs << "Invalid face index." << llendl;
+		llwarns << "Invalid face index." << llendl;
+		return NULL;
 	}
 
 	if (!mFaces[i])
 	{
-		llerrs << "Null face found." << llendl;
+		llwarns << "Null face found." << llendl;
+		return NULL;
 	}
 	
 	return mFaces[i];
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 5b62dbc560c197bc558585544f54bda5a00343be..5f2a982ed313a2a8ce62a3f0ce6857d8cb965608 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -405,6 +405,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
 			{
 				LLDrawInfo& params = **k;
 
+				if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+				{ //FIXME!
+					llwarns << "Missing required components, skipping render batch." << llendl;
+					continue;
+				}
+
 				LLRenderPass::applyModelMatrix(params);
 
 				
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 0103373fd21a0432dd4e518a0c48a6ebdbbe3f81..ace3a20bbb1413545cbbf0ae68e9e5f01a6787ad 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -261,7 +261,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
 	sRenderingSkinned = TRUE;
 
 	gPipeline.bindDeferredShader(*sVertexProgram);
-	
+
+	sVertexProgram->setMinimumAlpha(0.2f);
+
 	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 }
 
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4108d69e820de82ad5b674ca935f9884883f7a27..49a20d5ef99f854f76357798063a689da07f07c4 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -44,11 +44,14 @@
 #include "llsky.h"
 #include "llviewercamera.h"
 #include "llviewertexturelist.h"
+#include "llvopartgroup.h"
 #include "llvosky.h"
 #include "llvovolume.h"
 #include "pipeline.h"
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
+#include "llviewershadermgr.h"
+
 
 #define LL_MAX_INDICES_COUNT 1000000
 
@@ -56,7 +59,6 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
 
 #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
 
-
 /*
 For each vertex, given:
 	B - binormal
@@ -161,7 +163,15 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
 	mGeomCount		= 0;
 	mGeomIndex		= 0;
 	mIndicesCount	= 0;
-	mIndicesIndex	= 0;
+	if (drawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
+		drawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES)
+	{ //indicate to LLParticlePartition that this particle is uninitialized
+		mIndicesIndex = 0xFFFFFFFF;
+	}
+	else
+	{
+		mIndicesIndex	= 0;
+	}
 	mIndexInTex = 0;
 	mTexture		= NULL;
 	mTEOffset		= -1;
@@ -177,12 +187,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
 
 	mFaceColor = LLColor4(1,0,0,1);
 
-	mLastVertexBuffer = mVertexBuffer;
-	mLastGeomCount = mGeomCount;
-	mLastGeomIndex = mGeomIndex;
-	mLastIndicesCount = mIndicesCount;
-	mLastIndicesIndex = mIndicesIndex;
-
 	mImportanceToCamera = 0.f ;
 	mBoundingSphereRadius = 0.0f ;
 
@@ -203,6 +207,15 @@ void LLFace::destroy()
 		mTexture->removeFace(this) ;
 	}
 	
+	if (mDrawablep.notNull() &&
+		(mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
+		mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES) &&
+		mIndicesIndex != 0xFFFFFFFF)
+	{
+		LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
+		mIndicesIndex = 0xFFFFFFFF;
+	}
+
 	if (mDrawPoolp)
 	{
 		if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
@@ -372,7 +385,6 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)
 		mGeomCount    = num_vertices;
 		mIndicesCount = num_indices;
 		mVertexBuffer = NULL;
-		mLastVertexBuffer = NULL;
 	}
 
 	llassert(verify());
@@ -765,12 +777,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
 		LLMatrix4a mat_normal;
 		mat_normal.loadu(mat_normal_in);
 
-		//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
-		//{ //vertex buffer no longer valid
-		//	mVertexBuffer = NULL;
-		//	mLastVertexBuffer = NULL;
-		//}
-
 		//VECTORIZE THIS
 		LLVector4a min,max;
 	
@@ -1032,30 +1038,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to,  LLVector2* res_st_offs
 
 void LLFace::updateRebuildFlags()
 {
-	if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
-	{
-		BOOL moved = TRUE;
-		if (mLastVertexBuffer == mVertexBuffer && 
-			!mVertexBuffer->isEmpty())
-		{	//this face really doesn't need to be regenerated, try real hard not to do so
-			if (mLastGeomCount == mGeomCount &&
-				mLastGeomIndex == mGeomIndex &&
-				mLastIndicesCount == mIndicesCount &&
-				mLastIndicesIndex == mIndicesIndex)
-			{ //data is in same location in vertex buffer
-				moved = FALSE;
-			}
-		}
-		mLastMoveTime = gFrameTimeSeconds;
-		
-		if (moved)
-		{
-			mDrawablep->setState(LLDrawable::REBUILD_VOLUME);
-		}
+	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
+	{ //this rebuild is zero overhead (direct consequence of some change that affects this face)
+		mLastUpdateTime = gFrameTimeSeconds;
 	}
 	else
-	{
-		mLastUpdateTime = gFrameTimeSeconds;
+	{ //this rebuild is overhead (side effect of some change that does not affect this face)
+		mLastMoveTime = gFrameTimeSeconds;
 	}
 }
 
@@ -1094,6 +1083,73 @@ bool LLFace::canRenderAsMask()
 }
 
 
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_VOLUME("Volume VB Cache");
+
+//static 
+void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
+{
+	LLFastTimer t(FTM_FACE_GEOM_VOLUME);
+	U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
+				LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL;
+	
+	if (vf.mWeights)
+	{
+		mask |= LLVertexBuffer::MAP_WEIGHT4;
+	}
+
+	LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB);
+	vf.mVertexBuffer = buff;
+
+	buff->allocateBuffer(vf.mNumVertices, 0, true);
+
+	LLStrider<LLVector4a> f_vert;
+	LLStrider<LLVector3> f_binorm;
+	LLStrider<LLVector3> f_norm;
+	LLStrider<LLVector2> f_tc;
+
+	buff->getBinormalStrider(f_binorm);
+	buff->getVertexStrider(f_vert);
+	buff->getNormalStrider(f_norm);
+	buff->getTexCoord0Strider(f_tc);
+
+	for (U32 i = 0; i < vf.mNumVertices; ++i)
+	{
+		*f_vert++ = vf.mPositions[i];
+		(*f_binorm++).set(vf.mBinormals[i].getF32ptr());
+		*f_tc++ = vf.mTexCoords[i];
+		(*f_norm++).set(vf.mNormals[i].getF32ptr());
+	}
+
+	if (vf.mWeights)
+	{
+		LLStrider<LLVector4> f_wght;
+		buff->getWeight4Strider(f_wght);
+		for (U32 i = 0; i < vf.mNumVertices; ++i)
+		{
+			(*f_wght++).set(vf.mWeights[i].getF32ptr());
+		}
+	}
+
+	buff->flush();
+}
+
+//helper function for pushing primitives for transform shaders and cleaning up
+//uninitialized data on the tail, plus tracking number of expected primitives
+void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
+{
+	if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping
+	{
+		//push source primitives
+		buff->drawArrays(LLRender::POINTS, 0, source_count);
+		U32 tail = dest_count-source_count;
+		for (U32 i = 0; i < tail; ++i)
+		{ //copy last source primitive into each element in tail
+			buff->drawArrays(LLRender::POINTS, source_count-1, 1);
+		}
+		gPipeline.mTransformFeedbackPrimitives += dest_count;
+	}
+}
+
 static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position");
 static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal");
@@ -1111,7 +1167,6 @@ static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default");
 static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick");
 static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform");
 static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform");
-
 static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");
 
 BOOL LLFace::getGeometryVolume(const LLVolume& volume,
@@ -1144,9 +1199,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 					<< " VF Num Indices: " << num_indices
 					<< " Indices Index: " << mIndicesIndex
 					<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
-			llwarns	<< "Last Indices Count: " << mLastIndicesCount
-					<< " Last Indices Index: " << mLastIndicesIndex
-					<< " Face Index: " << f
+			llwarns	<< " Face Index: " << f
 					<< " Pool Type: " << mPoolType << llendl;
 			return FALSE;
 		}
@@ -1284,17 +1337,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	LLMatrix4a mat_normal;
 	mat_normal.loadu(mat_norm_in);
 	
-	//if it's not fullbright and has no normals, bake sunlight based on face normal
-	//bool bake_sunlight = !getTextureEntry()->getFullbright() &&
-	//  !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
-
 	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
-
+	bool do_xform = false;
 	if (rebuild_tcoord)
 	{
-		LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
-		bool do_xform;
-			
 		if (tep)
 		{
 			r  = tep->getRotation();
@@ -1323,599 +1369,759 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 		{
 			do_xform = false;
 		}
+	}
+	
+	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+	if (use_transform_feedback &&
+		gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+		mVertexBuffer->useVBOs() && //target buffer is in VRAM
+		!rebuild_weights && //TODO: add support for weights
+		!volume.isUnique()) //source volume is NOT flexi
+	{ //use transform feedback to pack vertex buffer
+
+		LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+
+		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
+		{
+			mVObjp->getVolume()->genBinormals(f);
+			LLFace::cacheFaceInVRAM(vf);
+			buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+		}		
+
+		LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
+		
+		gGL.pushMatrix();
+		gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix);
+
+		if (rebuild_pos)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_POSITION);
+			gTransformPositionProgram.bind();
+
+			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
+
+			U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+
+			S32 val = 0;
+			U8* vp = (U8*) &val;
+			vp[0] = index;
+			vp[1] = 0;
+			vp[2] = 0;
+			vp[3] = 0;
+			
+			gTransformPositionProgram.uniform1i("texture_index_in", val);
+			glBeginTransformFeedback(GL_POINTS);
+			buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+			push_for_transform(buff, vf.mNumVertices, mGeomCount);
+
+			glEndTransformFeedback();
+		}
+
+		if (rebuild_color)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_COLOR);
+			gTransformColorProgram.bind();
+			
+			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
+
+			S32 val = *((S32*) color.mV);
+
+			gTransformColorProgram.uniform1i("color_in", val);
+			glBeginTransformFeedback(GL_POINTS);
+			buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+			push_for_transform(buff, vf.mNumVertices, mGeomCount);
+			glEndTransformFeedback();
+		}
+
+		if (rebuild_emissive)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+			gTransformColorProgram.bind();
+			
+			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
+
+			U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+
+			S32 glow32 = glow |
+						 (glow << 8) |
+						 (glow << 16) |
+						 (glow << 24);
+
+			gTransformColorProgram.uniform1i("color_in", glow32);
+			glBeginTransformFeedback(GL_POINTS);
+			buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+			push_for_transform(buff, vf.mNumVertices, mGeomCount);
+			glEndTransformFeedback();
+		}
+
+		if (rebuild_normal)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+			gTransformNormalProgram.bind();
+			
+			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
 						
-		//bump setup
-		LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
-		LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
-		LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
+			glBeginTransformFeedback(GL_POINTS);
+			buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
+			push_for_transform(buff, vf.mNumVertices, mGeomCount);
+			glEndTransformFeedback();
+		}
 
-		LLQuaternion bump_quat;
-		if (mDrawablep->isActive())
+		if (rebuild_binormal)
 		{
-			bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
+			LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+			gTransformBinormalProgram.bind();
+			
+			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
+						
+			glBeginTransformFeedback(GL_POINTS);
+			buff->setBuffer(LLVertexBuffer::MAP_BINORMAL);
+			push_for_transform(buff, vf.mNumVertices, mGeomCount);
+			glEndTransformFeedback();
 		}
-		
-		if (bump_code)
+
+		if (rebuild_tcoord)
 		{
-			mVObjp->getVolume()->genBinormals(f);
-			F32 offset_multiple; 
-			switch( bump_code )
-			{
-				case BE_NO_BUMP:
-				offset_multiple = 0.f;
-				break;
-				case BE_BRIGHTNESS:
-				case BE_DARKNESS:
-				if( mTexture.notNull() && mTexture->hasGLTexture())
-				{
-					// Offset by approximately one texel
-					S32 cur_discard = mTexture->getDiscardLevel();
-					S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
-					max_size <<= cur_discard;
-					const F32 ARTIFICIAL_OFFSET = 2.f;
-					offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
-				}
-				else
-				{
-					offset_multiple = 1.f/256;
-				}
-				break;
+			LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+			gTransformTexCoordProgram.bind();
+			
+			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
+						
+			glBeginTransformFeedback(GL_POINTS);
+			buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+			push_for_transform(buff, vf.mNumVertices, mGeomCount);
+			glEndTransformFeedback();
 
-				default:  // Standard bumpmap textures.  Assumed to be 256x256
-				offset_multiple = 1.f / 256;
-				break;
-			}
+			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
 
-			F32 s_scale = 1.f;
-			F32 t_scale = 1.f;
-			if( tep )
+			if (do_bump)
 			{
-				tep->getScale( &s_scale, &t_scale );
-			}
-			// Use the nudged south when coming from above sun angle, such
-			// that emboss mapping always shows up on the upward faces of cubes when 
-			// it's noon (since a lot of builders build with the sun forced to noon).
-			LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir;
-			LLVector3   moon_ray = gSky.getMoonDirection();
-			LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
-
-			bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
-			bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
+				mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
+				glBeginTransformFeedback(GL_POINTS);
+				buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+				push_for_transform(buff, vf.mNumVertices, mGeomCount);
+				glEndTransformFeedback();
+			}				
 		}
 
-		U8 texgen = getTextureEntry()->getTexGen();
-		if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
-		{ //planar texgen needs binormals
-			mVObjp->getVolume()->genBinormals(f);
+		glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
+
+		gGL.popMatrix();
+
+		if (cur_shader)
+		{
+			cur_shader->bind();
 		}
+	}
+	else
+#endif
+	{
+		//if it's not fullbright and has no normals, bake sunlight based on face normal
+		//bool bake_sunlight = !getTextureEntry()->getFullbright() &&
+		//  !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
 
-		U8 tex_mode = 0;
-	
-		if (isState(TEXTURE_ANIM))
+		if (rebuild_tcoord)
 		{
-			LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	
-			tex_mode = vobj->mTexAnimMode;
+			LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+									
+			//bump setup
+			LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
+			LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
+			LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
 
-			if (!tex_mode)
+			LLQuaternion bump_quat;
+			if (mDrawablep->isActive())
 			{
-				clearState(TEXTURE_ANIM);
+				bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
 			}
-			else
+		
+			if (bump_code)
 			{
-				os = ot = 0.f;
-				r = 0.f;
-				cos_ang = 1.f;
-				sin_ang = 0.f;
-				ms = mt = 1.f;
+				mVObjp->getVolume()->genBinormals(f);
+				F32 offset_multiple; 
+				switch( bump_code )
+				{
+					case BE_NO_BUMP:
+					offset_multiple = 0.f;
+					break;
+					case BE_BRIGHTNESS:
+					case BE_DARKNESS:
+					if( mTexture.notNull() && mTexture->hasGLTexture())
+					{
+						// Offset by approximately one texel
+						S32 cur_discard = mTexture->getDiscardLevel();
+						S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
+						max_size <<= cur_discard;
+						const F32 ARTIFICIAL_OFFSET = 2.f;
+						offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
+					}
+					else
+					{
+						offset_multiple = 1.f/256;
+					}
+					break;
 
-				do_xform = false;
+					default:  // Standard bumpmap textures.  Assumed to be 256x256
+					offset_multiple = 1.f / 256;
+					break;
+				}
+
+				F32 s_scale = 1.f;
+				F32 t_scale = 1.f;
+				if( tep )
+				{
+					tep->getScale( &s_scale, &t_scale );
+				}
+				// Use the nudged south when coming from above sun angle, such
+				// that emboss mapping always shows up on the upward faces of cubes when 
+				// it's noon (since a lot of builders build with the sun forced to noon).
+				LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir;
+				LLVector3   moon_ray = gSky.getMoonDirection();
+				LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
+
+				bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
+				bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
 			}
 
-			if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
-			{ //don't override texture transform during tc bake
-				tex_mode = 0;
+			U8 texgen = getTextureEntry()->getTexGen();
+			if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+			{ //planar texgen needs binormals
+				mVObjp->getVolume()->genBinormals(f);
 			}
-		}
 
-		LLVector4a scalea;
-		scalea.load3(scale.mV);
+			U8 tex_mode = 0;
+	
+			if (isState(TEXTURE_ANIM))
+			{
+				LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	
+				tex_mode = vobj->mTexAnimMode;
+
+				if (!tex_mode)
+				{
+					clearState(TEXTURE_ANIM);
+				}
+				else
+				{
+					os = ot = 0.f;
+					r = 0.f;
+					cos_ang = 1.f;
+					sin_ang = 0.f;
+					ms = mt = 1.f;
+
+					do_xform = false;
+				}
+
+				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
+				{ //don't override texture transform during tc bake
+					tex_mode = 0;
+				}
+			}
 
-		bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
-		bool do_tex_mat = tex_mode && mTextureMatrix;
+			LLVector4a scalea;
+			scalea.load3(scale.mV);
 
-		if (!in_atlas && !do_bump)
-		{ //not in atlas or not bump mapped, might be able to do a cheap update
-			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
+			bool do_tex_mat = tex_mode && mTextureMatrix;
 
-			if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
-			{
-				LLFastTimer t(FTM_FACE_TEX_QUICK);
-				if (!do_tex_mat)
+			if (!in_atlas && !do_bump)
+			{ //not in atlas or not bump mapped, might be able to do a cheap update
+				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+
+				if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
 				{
-					if (!do_xform)
-					{
-						LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
-						LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
-					}
-					else
+					LLFastTimer t(FTM_FACE_TEX_QUICK);
+					if (!do_tex_mat)
 					{
-						LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
-						F32* dst = (F32*) tex_coords.get();
-						LLVector4a* src = (LLVector4a*) vf.mTexCoords;
+						if (!do_xform)
+						{
+							LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
+							LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
+						}
+						else
+						{
+							LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
+							F32* dst = (F32*) tex_coords.get();
+							LLVector4a* src = (LLVector4a*) vf.mTexCoords;
 
-						LLVector4a trans;
-						trans.splat(-0.5f);
+							LLVector4a trans;
+							trans.splat(-0.5f);
 
-						LLVector4a rot0;
-						rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
+							LLVector4a rot0;
+							rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
 
-						LLVector4a rot1;
-						rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
+							LLVector4a rot1;
+							rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
 
-						LLVector4a scale;
-						scale.set(ms, mt, ms, mt);
+							LLVector4a scale;
+							scale.set(ms, mt, ms, mt);
 
-						LLVector4a offset;
-						offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
+							LLVector4a offset;
+							offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
 
-						LLVector4Logical mask;
-						mask.clear();
-						mask.setElement<2>();
-						mask.setElement<3>();
+							LLVector4Logical mask;
+							mask.clear();
+							mask.setElement<2>();
+							mask.setElement<3>();
 
-						U32 count = num_vertices/2 + num_vertices%2;
+							U32 count = num_vertices/2 + num_vertices%2;
 
-						for (S32 i = 0; i < count; i++)
+							for (S32 i = 0; i < count; i++)
+							{	
+								LLVector4a res = *src++;
+								xform4a(res, trans, mask, rot0, rot1, offset, scale);
+								res.store4a(dst);
+								dst += 4;
+							}
+						}
+					}
+					else
+					{ //do tex mat, no texgen, no atlas, no bump
+						for (S32 i = 0; i < num_vertices; i++)
 						{	
-							LLVector4a res = *src++;
-							xform4a(res, trans, mask, rot0, rot1, offset, scale);
-							res.store4a(dst);
-							dst += 4;
+							LLVector2 tc(vf.mTexCoords[i]);
+							//LLVector4a& norm = vf.mNormals[i];
+							//LLVector4a& center = *(vf.mCenter);
+
+							LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+							tmp = tmp * *mTextureMatrix;
+							tc.mV[0] = tmp.mV[0];
+							tc.mV[1] = tmp.mV[1];
+							*tex_coords++ = tc;	
 						}
 					}
 				}
 				else
-				{ //do tex mat, no texgen, no atlas, no bump
-					for (S32 i = 0; i < num_vertices; i++)
-					{	
-						LLVector2 tc(vf.mTexCoords[i]);
-						//LLVector4a& norm = vf.mNormals[i];
-						//LLVector4a& center = *(vf.mCenter);
-
-						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
-						tmp = tmp * *mTextureMatrix;
-						tc.mV[0] = tmp.mV[0];
-						tc.mV[1] = tmp.mV[1];
-						*tex_coords++ = tc;	
-					}
-				}
-			}
-			else
-			{ //no bump, no atlas, tex gen planar
-				LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
-				if (do_tex_mat)
-				{
-					for (S32 i = 0; i < num_vertices; i++)
-					{	
-						LLVector2 tc(vf.mTexCoords[i]);
-						LLVector4a& norm = vf.mNormals[i];
-						LLVector4a& center = *(vf.mCenter);
-						LLVector4a vec = vf.mPositions[i];	
-						vec.mul(scalea);
-						planarProjection(tc, norm, center, vec);
+				{ //no bump, no atlas, tex gen planar
+					LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
+					if (do_tex_mat)
+					{
+						for (S32 i = 0; i < num_vertices; i++)
+						{	
+							LLVector2 tc(vf.mTexCoords[i]);
+							LLVector4a& norm = vf.mNormals[i];
+							LLVector4a& center = *(vf.mCenter);
+							LLVector4a vec = vf.mPositions[i];	
+							vec.mul(scalea);
+							planarProjection(tc, norm, center, vec);
 						
-						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
-						tmp = tmp * *mTextureMatrix;
-						tc.mV[0] = tmp.mV[0];
-						tc.mV[1] = tmp.mV[1];
+							LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+							tmp = tmp * *mTextureMatrix;
+							tc.mV[0] = tmp.mV[0];
+							tc.mV[1] = tmp.mV[1];
 				
-						*tex_coords++ = tc;	
+							*tex_coords++ = tc;	
+						}
 					}
-				}
-				else
-				{
-					for (S32 i = 0; i < num_vertices; i++)
-					{	
-						LLVector2 tc(vf.mTexCoords[i]);
-						LLVector4a& norm = vf.mNormals[i];
-						LLVector4a& center = *(vf.mCenter);
-						LLVector4a vec = vf.mPositions[i];	
-						vec.mul(scalea);
-						planarProjection(tc, norm, center, vec);
+					else
+					{
+						for (S32 i = 0; i < num_vertices; i++)
+						{	
+							LLVector2 tc(vf.mTexCoords[i]);
+							LLVector4a& norm = vf.mNormals[i];
+							LLVector4a& center = *(vf.mCenter);
+							LLVector4a vec = vf.mPositions[i];	
+							vec.mul(scalea);
+							planarProjection(tc, norm, center, vec);
 						
-						xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+							xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
 
-						*tex_coords++ = tc;	
+							*tex_coords++ = tc;	
+						}
 					}
 				}
-			}
 
-			if (map_range)
-			{
-				mVertexBuffer->flush();
+				if (map_range)
+				{
+					mVertexBuffer->flush();
+				}
 			}
-		}
-		else
-		{ //either bump mapped or in atlas, just do the whole expensive loop
-			LLFastTimer t(FTM_FACE_TEX_DEFAULT);
-			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
+			else
+			{ //either bump mapped or in atlas, just do the whole expensive loop
+				LLFastTimer t(FTM_FACE_TEX_DEFAULT);
+				mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
 
-			std::vector<LLVector2> bump_tc;
+				std::vector<LLVector2> bump_tc;
 		
-			for (S32 i = 0; i < num_vertices; i++)
-			{	
-				LLVector2 tc(vf.mTexCoords[i]);
+				for (S32 i = 0; i < num_vertices; i++)
+				{	
+					LLVector2 tc(vf.mTexCoords[i]);
 			
-				LLVector4a& norm = vf.mNormals[i];
+					LLVector4a& norm = vf.mNormals[i];
 				
-				LLVector4a& center = *(vf.mCenter);
+					LLVector4a& center = *(vf.mCenter);
 		   
-				if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
-				{
-					LLVector4a vec = vf.mPositions[i];
+					if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+					{
+						LLVector4a vec = vf.mPositions[i];
 				
-					vec.mul(scalea);
+						vec.mul(scalea);
 
-					switch (texgen)
+						switch (texgen)
+						{
+							case LLTextureEntry::TEX_GEN_PLANAR:
+								planarProjection(tc, norm, center, vec);
+								break;
+							case LLTextureEntry::TEX_GEN_SPHERICAL:
+								sphericalProjection(tc, norm, center, vec);
+								break;
+							case LLTextureEntry::TEX_GEN_CYLINDRICAL:
+								cylindricalProjection(tc, norm, center, vec);
+								break;
+							default:
+								break;
+						}		
+					}
+
+					if (tex_mode && mTextureMatrix)
 					{
-						case LLTextureEntry::TEX_GEN_PLANAR:
-							planarProjection(tc, norm, center, vec);
+						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+						tmp = tmp * *mTextureMatrix;
+						tc.mV[0] = tmp.mV[0];
+						tc.mV[1] = tmp.mV[1];
+					}
+					else
+					{
+						xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+					}
+
+					if(in_atlas)
+					{
+						//
+						//manually calculate tex-coord per vertex for varying address modes.
+						//should be removed if shader can handle this.
+						//
+
+						S32 int_part = 0 ;
+						switch(mTexture->getAddressMode())
+						{
+						case LLTexUnit::TAM_CLAMP:
+							if(tc.mV[0] < 0.f)
+							{
+								tc.mV[0] = 0.f ;
+							}
+							else if(tc.mV[0] > 1.f)
+							{
+								tc.mV[0] = 1.f;
+							}
+
+							if(tc.mV[1] < 0.f)
+							{
+								tc.mV[1] = 0.f ;
+							}
+							else if(tc.mV[1] > 1.f)
+							{
+								tc.mV[1] = 1.f;
+							}
 							break;
-						case LLTextureEntry::TEX_GEN_SPHERICAL:
-							sphericalProjection(tc, norm, center, vec);
+						case LLTexUnit::TAM_MIRROR:
+							if(tc.mV[0] < 0.f)
+							{
+								tc.mV[0] = -tc.mV[0] ;
+							}
+							int_part = (S32)tc.mV[0] ;
+							if(int_part & 1) //odd number
+							{
+								tc.mV[0] = int_part + 1 - tc.mV[0] ;
+							}
+							else //even number
+							{
+								tc.mV[0] -= int_part ;
+							}
+
+							if(tc.mV[1] < 0.f)
+							{
+								tc.mV[1] = -tc.mV[1] ;
+							}
+							int_part = (S32)tc.mV[1] ;
+							if(int_part & 1) //odd number
+							{
+								tc.mV[1] = int_part + 1 - tc.mV[1] ;
+							}
+							else //even number
+							{
+								tc.mV[1] -= int_part ;
+							}
 							break;
-						case LLTextureEntry::TEX_GEN_CYLINDRICAL:
-							cylindricalProjection(tc, norm, center, vec);
+						case LLTexUnit::TAM_WRAP:
+							if(tc.mV[0] > 1.f)
+								tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
+							else if(tc.mV[0] < -1.f)
+								tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
+
+							if(tc.mV[1] > 1.f)
+								tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
+							else if(tc.mV[1] < -1.f)
+								tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
+
+							if(tc.mV[0] < 0.f)
+							{
+								tc.mV[0] = 1.0f + tc.mV[0] ;
+							}
+							if(tc.mV[1] < 0.f)
+							{
+								tc.mV[1] = 1.0f + tc.mV[1] ;
+							}
 							break;
 						default:
 							break;
-					}		
-				}
+						}
+				
+						tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
+						tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
+					}
+				
 
-				if (tex_mode && mTextureMatrix)
-				{
-					LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
-					tmp = tmp * *mTextureMatrix;
-					tc.mV[0] = tmp.mV[0];
-					tc.mV[1] = tmp.mV[1];
+					*tex_coords++ = tc;
+					if (do_bump)
+					{
+						bump_tc.push_back(tc);
+					}
 				}
-				else
+
+				if (map_range)
 				{
-					xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+					mVertexBuffer->flush();
 				}
 
-				if(in_atlas)
+				if (do_bump)
 				{
-					//
-					//manually calculate tex-coord per vertex for varying address modes.
-					//should be removed if shader can handle this.
-					//
-
-					S32 int_part = 0 ;
-					switch(mTexture->getAddressMode())
+					mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
+		
+					for (S32 i = 0; i < num_vertices; i++)
 					{
-					case LLTexUnit::TAM_CLAMP:
-						if(tc.mV[0] < 0.f)
-						{
-							tc.mV[0] = 0.f ;
-						}
-						else if(tc.mV[0] > 1.f)
-						{
-							tc.mV[0] = 1.f;
-						}
-
-						if(tc.mV[1] < 0.f)
-						{
-							tc.mV[1] = 0.f ;
-						}
-						else if(tc.mV[1] > 1.f)
-						{
-							tc.mV[1] = 1.f;
-						}
-						break;
-					case LLTexUnit::TAM_MIRROR:
-						if(tc.mV[0] < 0.f)
-						{
-							tc.mV[0] = -tc.mV[0] ;
-						}
-						int_part = (S32)tc.mV[0] ;
-						if(int_part & 1) //odd number
-						{
-							tc.mV[0] = int_part + 1 - tc.mV[0] ;
-						}
-						else //even number
+						LLVector4a tangent;
+						tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
+
+						LLMatrix4a tangent_to_object;
+						tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
+						LLVector4a t;
+						tangent_to_object.rotate(binormal_dir, t);
+						LLVector4a binormal;
+						mat_normal.rotate(t, binormal);
+						
+						//VECTORIZE THIS
+						if (mDrawablep->isActive())
 						{
-							tc.mV[0] -= int_part ;
+							LLVector3 t;
+							t.set(binormal.getF32ptr());
+							t *= bump_quat;
+							binormal.load3(t.mV);
 						}
 
-						if(tc.mV[1] < 0.f)
-						{
-							tc.mV[1] = -tc.mV[1] ;
-						}
-						int_part = (S32)tc.mV[1] ;
-						if(int_part & 1) //odd number
-						{
-							tc.mV[1] = int_part + 1 - tc.mV[1] ;
-						}
-						else //even number
-						{
-							tc.mV[1] -= int_part ;
-						}
-						break;
-					case LLTexUnit::TAM_WRAP:
-						if(tc.mV[0] > 1.f)
-							tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
-						else if(tc.mV[0] < -1.f)
-							tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
-
-						if(tc.mV[1] > 1.f)
-							tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
-						else if(tc.mV[1] < -1.f)
-							tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
-
-						if(tc.mV[0] < 0.f)
-						{
-							tc.mV[0] = 1.0f + tc.mV[0] ;
-						}
-						if(tc.mV[1] < 0.f)
-						{
-							tc.mV[1] = 1.0f + tc.mV[1] ;
-						}
-						break;
-					default:
-						break;
+						binormal.normalize3fast();
+						LLVector2 tc = bump_tc[i];
+						tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
+					
+						*tex_coords2++ = tc;
 					}
-				
-					tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
-					tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
-				}
-				
-
-				*tex_coords++ = tc;
-				if (do_bump)
-				{
-					bump_tc.push_back(tc);
-				}
-			}
-
-			if (map_range)
-			{
-				mVertexBuffer->flush();
-			}
 
-			if (do_bump)
-			{
-				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
-		
-				for (S32 i = 0; i < num_vertices; i++)
-				{
-					LLVector4a tangent;
-					tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
-
-					LLMatrix4a tangent_to_object;
-					tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
-					LLVector4a t;
-					tangent_to_object.rotate(binormal_dir, t);
-					LLVector4a binormal;
-					mat_normal.rotate(t, binormal);
-						
-					//VECTORIZE THIS
-					if (mDrawablep->isActive())
+					if (map_range)
 					{
-						LLVector3 t;
-						t.set(binormal.getF32ptr());
-						t *= bump_quat;
-						binormal.load3(t.mV);
+						mVertexBuffer->flush();
 					}
-
-					binormal.normalize3fast();
-					LLVector2 tc = bump_tc[i];
-					tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
-					
-					*tex_coords2++ = tc;
-				}
-
-				if (map_range)
-				{
-					mVertexBuffer->flush();
 				}
 			}
 		}
-	}
 
-	if (rebuild_pos)
-	{
-		LLFastTimer t(FTM_FACE_GEOM_POSITION);
-		llassert(num_vertices > 0);
+		if (rebuild_pos)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_POSITION);
+			llassert(num_vertices > 0);
 		
-		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
+			mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
 			
 
-		LLMatrix4a mat_vert;
-		mat_vert.loadu(mat_vert_in);
+			LLMatrix4a mat_vert;
+			mat_vert.loadu(mat_vert_in);
 
-		LLVector4a* src = vf.mPositions;
-		volatile F32* dst = (volatile F32*) vert.get();
+			LLVector4a* src = vf.mPositions;
+			volatile F32* dst = (volatile F32*) vert.get();
 
-		volatile F32* end = dst+num_vertices*4;
-		LLVector4a res;
+			volatile F32* end = dst+num_vertices*4;
+			LLVector4a res;
 
-		LLVector4a texIdx;
+			LLVector4a texIdx;
 
-		U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+			U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
 
-		F32 val = 0.f;
-		U8* vp = (U8*) &val;
-		vp[0] = index;
-		vp[1] = 0;
-		vp[2] = 0;
-		vp[3] = 0;
+			F32 val = 0.f;
+			U8* vp = (U8*) &val;
+			vp[0] = index;
+			vp[1] = 0;
+			vp[2] = 0;
+			vp[3] = 0;
 
-		llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
+			llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
 
-		LLVector4Logical mask;
-		mask.clear();
-		mask.setElement<3>();
+			LLVector4Logical mask;
+			mask.clear();
+			mask.setElement<3>();
 		
-		texIdx.set(0,0,0,val);
+			texIdx.set(0,0,0,val);
 
-		{
-			LLFastTimer t(FTM_FACE_POSITION_STORE);
-			LLVector4a tmp;
-
-			do
-			{	
-				mat_vert.affineTransform(*src++, res);
-				tmp.setSelectWithMask(mask, texIdx, res);
-				tmp.store4a((F32*) dst);
-				dst += 4;
+			{
+				LLFastTimer t(FTM_FACE_POSITION_STORE);
+				LLVector4a tmp;
+
+				do
+				{	
+					mat_vert.affineTransform(*src++, res);
+					tmp.setSelectWithMask(mask, texIdx, res);
+					tmp.store4a((F32*) dst);
+					dst += 4;
+				}
+				while(dst < end);
 			}
-			while(dst < end);
-		}
 
-		{
-			LLFastTimer t(FTM_FACE_POSITION_PAD);
-			S32 aligned_pad_vertices = mGeomCount - num_vertices;
-			res.set(res[0], res[1], res[2], 0.f);
+			{
+				LLFastTimer t(FTM_FACE_POSITION_PAD);
+				S32 aligned_pad_vertices = mGeomCount - num_vertices;
+				res.set(res[0], res[1], res[2], 0.f);
 
-			while (aligned_pad_vertices > 0)
+				while (aligned_pad_vertices > 0)
+				{
+					--aligned_pad_vertices;
+					res.store4a((F32*) dst);
+					dst += 4;
+				}
+			}
+
+			if (map_range)
 			{
-				--aligned_pad_vertices;
-				res.store4a((F32*) dst);
-				dst += 4;
+				mVertexBuffer->flush();
 			}
 		}
 
-		if (map_range)
-		{
-			mVertexBuffer->flush();
-		}
-	}
 		
-	if (rebuild_normal)
-	{
-		LLFastTimer t(FTM_FACE_GEOM_NORMAL);
-		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
-		F32* normals = (F32*) norm.get();
+		if (rebuild_normal)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
+			F32* normals = (F32*) norm.get();
 	
-		for (S32 i = 0; i < num_vertices; i++)
-		{	
-			LLVector4a normal;
-			mat_normal.rotate(vf.mNormals[i], normal);
-			normal.normalize3fast();
-			normal.store4a(normals);
-			normals += 4;
-		}
+			for (S32 i = 0; i < num_vertices; i++)
+			{	
+				LLVector4a normal;
+				mat_normal.rotate(vf.mNormals[i], normal);
+				normal.normalize3fast();
+				normal.store4a(normals);
+				normals += 4;
+			}
 
-		if (map_range)
-		{
-			mVertexBuffer->flush();
+			if (map_range)
+			{
+				mVertexBuffer->flush();
+			}
 		}
-	}
 		
-	if (rebuild_binormal)
-	{
-		LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
-		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
-		F32* binormals = (F32*) binorm.get();
+		if (rebuild_binormal)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
+			F32* binormals = (F32*) binorm.get();
 		
-		for (S32 i = 0; i < num_vertices; i++)
-		{	
-			LLVector4a binormal;
-			mat_normal.rotate(vf.mBinormals[i], binormal);
-			binormal.normalize3fast();
-			binormal.store4a(binormals);
-			binormals += 4;
-		}
+			for (S32 i = 0; i < num_vertices; i++)
+			{	
+				LLVector4a binormal;
+				mat_normal.rotate(vf.mBinormals[i], binormal);
+				binormal.normalize3fast();
+				binormal.store4a(binormals);
+				binormals += 4;
+			}
 
-		if (map_range)
-		{
-			mVertexBuffer->flush();
+			if (map_range)
+			{
+				mVertexBuffer->flush();
+			}
 		}
-	}
 	
-	if (rebuild_weights && vf.mWeights)
-	{
-		LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
-		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
-		F32* weights = (F32*) wght.get();
-		LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
-		if (map_range)
+		if (rebuild_weights && vf.mWeights)
 		{
-			mVertexBuffer->flush();
+			LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
+			mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
+			F32* weights = (F32*) wght.get();
+			LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
+			if (map_range)
+			{
+				mVertexBuffer->flush();
+			}
 		}
-	}
 
-	if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
-	{
-		LLFastTimer t(FTM_FACE_GEOM_COLOR);
-		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
+		if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
+		{
+			LLFastTimer t(FTM_FACE_GEOM_COLOR);
+			mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
 
-		LLVector4a src;
+			LLVector4a src;
 
-		U32 vec[4];
-		vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
+			U32 vec[4];
+			vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
 		
-		src.loadua((F32*) vec);
+			src.loadua((F32*) vec);
 
-		F32* dst = (F32*) colors.get();
-		S32 num_vecs = num_vertices/4;
-		if (num_vertices%4 > 0)
-		{
-			++num_vecs;
-		}
+			F32* dst = (F32*) colors.get();
+			S32 num_vecs = num_vertices/4;
+			if (num_vertices%4 > 0)
+			{
+				++num_vecs;
+			}
 
-		for (S32 i = 0; i < num_vecs; i++)
-		{	
-			src.store4a(dst);
-			dst += 4;
-		}
+			for (S32 i = 0; i < num_vecs; i++)
+			{	
+				src.store4a(dst);
+				dst += 4;
+			}
 
-		if (map_range)
-		{
-			mVertexBuffer->flush();
+			if (map_range)
+			{
+				mVertexBuffer->flush();
+			}
 		}
-	}
 
-	if (rebuild_emissive)
-	{
-		LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
-		LLStrider<LLColor4U> emissive;
-		mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
+		if (rebuild_emissive)
+		{
+			LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+			LLStrider<LLColor4U> emissive;
+			mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
 
-		U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+			U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
 
-		LLVector4a src;
+			LLVector4a src;
 
 		
-		U32 glow32 = glow |
-					 (glow << 8) |
-					 (glow << 16) |
-					 (glow << 24);
+			U32 glow32 = glow |
+						 (glow << 8) |
+						 (glow << 16) |
+						 (glow << 24);
 
-		U32 vec[4];
-		vec[0] = vec[1] = vec[2] = vec[3] = glow32;
+			U32 vec[4];
+			vec[0] = vec[1] = vec[2] = vec[3] = glow32;
 		
-		src.loadua((F32*) vec);
+			src.loadua((F32*) vec);
 
-		F32* dst = (F32*) emissive.get();
-		S32 num_vecs = num_vertices/4;
-		if (num_vertices%4 > 0)
-		{
-			++num_vecs;
-		}
+			F32* dst = (F32*) emissive.get();
+			S32 num_vecs = num_vertices/4;
+			if (num_vertices%4 > 0)
+			{
+				++num_vecs;
+			}
 
-		for (S32 i = 0; i < num_vecs; i++)
-		{	
-			src.store4a(dst);
-			dst += 4;
-		}
+			for (S32 i = 0; i < num_vecs; i++)
+			{	
+				src.store4a(dst);
+				dst += 4;
+			}
 
-		if (map_range)
-		{
-			mVertexBuffer->flush();
+			if (map_range)
+			{
+				mVertexBuffer->flush();
+			}
 		}
 	}
+
 	if (rebuild_tcoord)
 	{
 		mTexExtents[0].setVec(0,0);
@@ -1932,12 +2138,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	}
 
 
-	mLastVertexBuffer = mVertexBuffer;
-	mLastGeomCount = mGeomCount;
-	mLastGeomIndex = mGeomIndex;
-	mLastIndicesCount = mIndicesCount;
-	mLastIndicesIndex = mIndicesIndex;
-
 	return TRUE;
 }
 
@@ -2516,7 +2716,6 @@ void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
 void LLFace::clearVertexBuffer()
 {
 	mVertexBuffer = NULL;
-	mLastVertexBuffer = NULL;
 }
 
 //static
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 82e4ab61b7d9d5695afbe08f0c929327eca019e6..76ea5c853ac9bb389ae7206bca94cd3052cb981a 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -83,6 +83,8 @@ class LLFace
 
 	static void initClass();
 
+	static void cacheFaceInVRAM(const LLVolumeFace& vf);
+
 public:
 	LLFace(LLDrawable* drawablep, LLViewerObject* objp)   { init(drawablep, objp); }
 	~LLFace()  { destroy(); }
@@ -222,7 +224,7 @@ class LLFace
 
 	//vertex buffer tracking
 	void setVertexBuffer(LLVertexBuffer* buffer);
-	void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
+	void clearVertexBuffer(); //sets mVertexBuffer to NULL
 	LLVertexBuffer* getVertexBuffer()	const	{ return mVertexBuffer; }
 	U32 getRiggedVertexBufferDataMask() const;
 	S32 getRiggedIndex(U32 type) const;
@@ -255,8 +257,7 @@ class LLFace
 
 private:
 	LLPointer<LLVertexBuffer> mVertexBuffer;
-	LLPointer<LLVertexBuffer> mLastVertexBuffer;
-	
+		
 	U32			mState;
 	LLFacePool*	mDrawPoolp;
 	U32			mPoolType;
@@ -269,12 +270,6 @@ class LLFace
 	U32			mIndicesIndex;		// index into draw pool for indices (yeah, I know!)
 	S32         mIndexInTex ;
 
-	//previous rebuild's geometry info
-	U16			mLastGeomCount;
-	U16			mLastGeomIndex;
-	U32			mLastIndicesCount;
-	U32			mLastIndicesIndex;
-
 	LLXformMatrix* mXform;
 	LLPointer<LLViewerTexture> mTexture;
 	LLPointer<LLDrawable> mDrawablep;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 575b613ccfcce44e41e09484073f2a19f2ffce0f..4cbc9cab4a1311628dcf1b88d9a68b3f0c0d5df9 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1191,7 +1191,7 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
 	}
 	else if (action == "paste")
 	{
-		pastFromClipboard();
+		pasteFromClipboard();
 	}
 	else if (action == "delete")
 	{
@@ -1239,7 +1239,7 @@ BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
 	return TRUE;
 }
 
-void LLFavoritesBarCtrl::pastFromClipboard() const
+void LLFavoritesBarCtrl::pasteFromClipboard() const
 {
 	LLInventoryModel* model = &gInventory;
 	if(model && isClipboardPasteable())
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2f75b3bb0eec119a4b66a660c6dd4a2abd5ea656..447d30f1f41d299c455180780613794164df61de 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -90,7 +90,7 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 	bool enableSelected(const LLSD& userdata);
 	void doToSelected(const LLSD& userdata);
 	BOOL isClipboardPasteable() const;
-	void pastFromClipboard() const;
+	void pasteFromClipboard() const;
 	
 	void showDropDownMenu();
 
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 8986a694f9902585e6c443b62ddd2f84f538b198..4bf5b26b3b0794f213ee116d17f6fae3440bfcf1 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -59,6 +59,7 @@ LLFilePicker LLFilePicker::sInstance;
 #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
 #define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
 #define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
+#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
 #endif
 
 //
@@ -218,6 +219,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
 		mOFN.lpstrFilter = SCRIPT_FILTER \
 			L"\0";
 		break;
+	case FFLOAD_DICTIONARY:
+		mOFN.lpstrFilter = DICTIONARY_FILTER \
+			L"\0";
+		break;
 	default:
 		res = FALSE;
 		break;
@@ -643,6 +648,16 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB
 								result = false;
 							}
 						}
+						else if (filter == FFLOAD_DICTIONARY)
+						{
+							if (fileInfo.filetype != 'DIC ' &&
+								fileInfo.filetype != 'XCU ' &&
+								(fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
+								 fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)))
+							{
+								result = false;
+							}
+						}
 						
 						if (fileInfo.extension)
 						{
@@ -1235,6 +1250,12 @@ static std::string add_script_filter_to_gtkchooser(GtkWindow *picker)
 							LLTrans::getString("script_files") + " (*.lsl)");
 }
 
+static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker)
+{
+	return add_simple_mime_filter_to_gtkchooser(picker,  "text/plain",
+							LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
+}
+
 BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
 {
 	BOOL rtn = FALSE;
@@ -1371,6 +1392,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
 		case FFLOAD_SCRIPT:
 			filtername = add_script_filter_to_gtkchooser(picker);
 			break;
+		case FFLOAD_DICTIONARY:
+			filtername = add_dictionary_filter_to_gtkchooser(picker);
+			break;
 		default:;
 			break;
 		}
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index a4d5d68ff58f51ddb93b15266de9856e5eaf492e..55c665b9c76a812efa9123d0826078d8a8291d24 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -85,6 +85,7 @@ class LLFilePicker
 		FFLOAD_MODEL = 9,
 		FFLOAD_COLLADA = 10,
 		FFLOAD_SCRIPT = 11,
+		FFLOAD_DICTIONARY = 12
 	};
 
 	enum ESaveFilter
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 32a533570a2669a06727b9f554109863d2604d85..11edb60712ed6c8b3f587b36892e54f1ed234ee0 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -368,7 +368,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 	LLPath *path = &volume->getPath();
 	if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) 
 	{
-		mVO->markForUpdate(TRUE);
+		//mVO->markForUpdate(TRUE);
 		if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0))
 		{
 			return;	// we did not get updated or initialized, proceeding without can be dangerous
@@ -729,7 +729,11 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
 	else if (!mUpdated || rotated)
 	{
 		volume->mDrawable->setState(LLDrawable::REBUILD_POSITION);
-		volume->dirtyMesh();
+		LLSpatialGroup* group = volume->mDrawable->getSpatialGroup();
+		if (group)
+		{
+			group->dirtyMesh();
+		}
 		volume->genBBoxes(isVolumeGlobal());
 	}
 			
@@ -814,15 +818,17 @@ LLQuaternion LLVolumeImplFlexible::getEndRotation()
 }//------------------------------------------------------------------
 
 
-void LLVolumeImplFlexible::updateRelativeXform()
+void LLVolumeImplFlexible::updateRelativeXform(bool force_identity)
 {
 	LLQuaternion delta_rot;
 	LLVector3 delta_pos, delta_scale;
 	LLVOVolume* vo = (LLVOVolume*) mVO;
 
+	bool use_identity = vo->mDrawable->isSpatialRoot() || force_identity;
+
 	//matrix from local space to parent relative/global space
-	delta_rot = vo->mDrawable->isSpatialRoot() ? LLQuaternion() : vo->mDrawable->getRotation();
-	delta_pos = vo->mDrawable->isSpatialRoot() ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
+	delta_rot = use_identity ? LLQuaternion() : vo->mDrawable->getRotation();
+	delta_pos = use_identity ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
 	delta_scale = LLVector3(1,1,1);
 
 	// Vertex transform (4x4)
diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h
index fef43d464d2dccb9dbffe439effe1246a0e8f514..371d6a077307ac56f96e0947ffa0897afbe7e214 100644
--- a/indra/newview/llflexibleobject.h
+++ b/indra/newview/llflexibleobject.h
@@ -89,7 +89,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
 		bool isVolumeGlobal() const { return true; }
 		bool isActive() const { return true; }
 		const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
-		void updateRelativeXform();
+		void updateRelativeXform(bool force_identity);
 		void doFlexibleUpdate(); // Called to update the simulation
 		void doFlexibleRebuild(); // Called to rebuild the geometry
 		void preRebuild();
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7d1bcba978a05a0257768b7edd31de57a02b58ba
--- /dev/null
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -0,0 +1,641 @@
+/** 
+ * @file llfloaterautoreplacesettings.cpp
+ * @brief Auto Replace List floater
+ *
+ * $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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * 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
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterautoreplacesettings.h"
+
+#include "llagentdata.h"
+#include "llcommandhandler.h"
+#include "llfloater.h"
+#include "lluictrlfactory.h"
+#include "llagent.h"
+#include "llpanel.h"
+#include "llbutton.h"
+#include "llcolorswatch.h"
+#include "llcombobox.h"
+#include "llview.h"
+#include "llhttpclient.h"
+#include "llbufferstream.h"
+#include "llcheckboxctrl.h"
+#include "llviewercontrol.h"
+
+#include "llui.h"
+#include "llcontrol.h"
+#include "llscrollingpanellist.h"
+#include "llautoreplace.h"
+#include "llfilepicker.h"
+#include "llfile.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+
+#include "llchat.h"
+#include "llinventorymodel.h"
+#include "llhost.h"
+#include "llassetstorage.h"
+#include "roles_constants.h"
+#include "llviewertexteditor.h"
+#include <boost/tokenizer.hpp>
+
+#include <iosfwd>
+#include "llfloaterreg.h"
+#include "llinspecttoast.h"
+#include "llnotificationhandler.h"
+#include "llnotificationmanager.h"
+#include "llnotificationsutil.h"
+
+
+LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key)
+ : LLFloater(key)
+ , mSelectedListName("")
+ , mListNames(NULL)
+ , mReplacementsList(NULL)
+ , mKeyword(NULL)
+ , mPreviousKeyword("")
+ , mReplacement(NULL)
+{
+}
+
+void LLFloaterAutoReplaceSettings::onClose(bool app_quitting)
+{
+	cleanUp();
+}
+
+BOOL LLFloaterAutoReplaceSettings::postBuild(void)
+{
+	// get copies of the current settings that we will operate on
+	mEnabled  = gSavedSettings.getBOOL("AutoReplace");
+	LL_DEBUGS("AutoReplace") << ( mEnabled ? "enabled" : "disabled") << LL_ENDL;
+
+	mSettings = LLAutoReplace::getInstance()->getSettings();
+	
+	// global checkbox for whether or not autoreplace is active
+	LLUICtrl* enabledCheckbox = getChild<LLUICtrl>("autoreplace_enable");
+	enabledCheckbox->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onAutoReplaceToggled, this));
+	enabledCheckbox->setValue(LLSD(mEnabled));
+
+	// top row list creation and deletion
+	getChild<LLUICtrl>("autoreplace_import_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onImportList,this));
+	getChild<LLUICtrl>("autoreplace_export_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onExportList,this));
+	getChild<LLUICtrl>("autoreplace_new_list")->setCommitCallback(   boost::bind(&LLFloaterAutoReplaceSettings::onNewList,this));
+	getChild<LLUICtrl>("autoreplace_delete_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteList,this));
+
+	// the list of keyword->replacement lists
+	mListNames = getChild<LLScrollListCtrl>("autoreplace_list_name");
+	mListNames->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectList, this));
+	mListNames->setCommitOnSelectionChange(true);
+	
+	// list ordering
+	getChild<LLUICtrl>("autoreplace_list_up")->setCommitCallback(  boost::bind(&LLFloaterAutoReplaceSettings::onListUp,this));
+	getChild<LLUICtrl>("autoreplace_list_down")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onListDown,this));
+
+	// keyword->replacement entry add / delete
+	getChild<LLUICtrl>("autoreplace_add_entry")->setCommitCallback(   boost::bind(&LLFloaterAutoReplaceSettings::onAddEntry,this));
+	getChild<LLUICtrl>("autoreplace_delete_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteEntry,this));
+
+	// entry edits
+	mKeyword     = getChild<LLLineEditor>("autoreplace_keyword");
+	mReplacement = getChild<LLLineEditor>("autoreplace_replacement");
+	getChild<LLUICtrl>("autoreplace_save_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveEntry, this));
+
+	// dialog termination ( Save Changes / Cancel )
+	getChild<LLUICtrl>("autoreplace_save_changes")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveChanges, this));
+	getChild<LLUICtrl>("autoreplace_cancel")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onCancel, this));
+
+	// the list of keyword->replacement pairs
+	mReplacementsList = getChild<LLScrollListCtrl>("autoreplace_list_replacements");
+	mReplacementsList->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectEntry, this));
+	mReplacementsList->setCommitOnSelectionChange(true);
+
+	center();
+
+	mSelectedListName.clear();
+	updateListNames();
+	updateListNamesControls();
+	updateReplacementsList();
+
+	return true;
+}
+
+
+void LLFloaterAutoReplaceSettings::updateListNames()
+{
+	mListNames->deleteAllItems(); // start from scratch
+
+	LLSD listNames = mSettings.getListNames(); // Array of Strings
+   
+	for ( LLSD::array_const_iterator entry = listNames.beginArray(), end = listNames.endArray();
+		  entry != end;
+		  ++entry
+		 )
+	{
+		const std::string& listName = entry->asString();
+		mListNames->addSimpleElement(listName);
+	}
+
+	if (!mSelectedListName.empty())
+	{
+		mListNames->setSelectedByValue( LLSD(mSelectedListName), true );
+	}
+}
+
+void LLFloaterAutoReplaceSettings::updateListNamesControls()
+{
+	if ( mSelectedListName.empty() )
+	{
+		// There is no selected list
+
+		// Disable all controls that operate on the selected list
+		getChild<LLButton>("autoreplace_export_list")->setEnabled(false);
+		getChild<LLButton>("autoreplace_delete_list")->setEnabled(false);
+		getChild<LLButton>("autoreplace_list_up")->setEnabled(false);
+		getChild<LLButton>("autoreplace_list_down")->setEnabled(false);
+
+		mReplacementsList->deleteAllItems();
+	}
+	else
+	{
+		// Enable the controls that operate on the selected list
+		getChild<LLButton>("autoreplace_export_list")->setEnabled(true);
+		getChild<LLButton>("autoreplace_delete_list")->setEnabled(true);
+		getChild<LLButton>("autoreplace_list_up")->setEnabled(!selectedListIsFirst());
+		getChild<LLButton>("autoreplace_list_down")->setEnabled(!selectedListIsLast());
+	}
+}
+
+void LLFloaterAutoReplaceSettings::onSelectList()
+{
+	std::string previousSelectedListName = mSelectedListName;
+	// only one selection allowed
+	LLSD selected = mListNames->getSelectedValue();
+	if (selected.isDefined())
+	{
+		mSelectedListName = selected.asString();
+		LL_DEBUGS("AutoReplace")<<"selected list '"<<mSelectedListName<<"'"<<LL_ENDL;
+	}
+	else
+	{
+		mSelectedListName.clear();
+		LL_DEBUGS("AutoReplace")<<"unselected"<<LL_ENDL;
+	}
+
+	updateListNamesControls();
+
+	if ( previousSelectedListName != mSelectedListName )
+	{
+		updateReplacementsList();
+	}
+}
+
+void LLFloaterAutoReplaceSettings::onSelectEntry()
+{
+    LLSD selectedRow = mReplacementsList->getSelectedValue();
+	if (selectedRow.isDefined())
+	{
+		mPreviousKeyword = selectedRow.asString();
+		LL_DEBUGS("AutoReplace")<<"selected entry '"<<mPreviousKeyword<<"'"<<LL_ENDL;	
+		mKeyword->setValue(selectedRow);
+		std::string replacement = mSettings.replacementFor(mPreviousKeyword, mSelectedListName );
+		mReplacement->setValue(replacement);
+		enableReplacementEntry();		
+		mReplacement->setFocus(true);
+	}
+	else
+	{
+		// no entry selection, so the entry panel should be off
+		disableReplacementEntry();		
+		LL_DEBUGS("AutoReplace")<<"no row selected"<<LL_ENDL;
+	}
+}
+
+void LLFloaterAutoReplaceSettings::updateReplacementsList()
+{
+	// start from scratch, since this should only be called when the list changes
+	mReplacementsList->deleteAllItems();
+
+	if ( mSelectedListName.empty() )
+	{
+		mReplacementsList->setEnabled(false);
+		getChild<LLButton>("autoreplace_add_entry")->setEnabled(false);
+		disableReplacementEntry();		
+	}
+	else
+	{
+		// Populate the keyword->replacement list from the selected list
+		const LLSD* mappings = mSettings.getListEntries(mSelectedListName);
+		for ( LLSD::map_const_iterator entry = mappings->beginMap(), end = mappings->endMap();
+			  entry != end;
+			  entry++
+			 )
+		{
+			LLSD row;
+			row["id"] = entry->first;
+			row["columns"][0]["column"] = "keyword";
+			row["columns"][0]["value"]  = entry->first;
+			row["columns"][1]["column"] = "replacement";
+			row["columns"][1]["value"]  = entry->second;
+
+			mReplacementsList->addElement(row, ADD_BOTTOM);
+		}
+
+		mReplacementsList->deselectAllItems(false /* don't call commit */);
+		mReplacementsList->setEnabled(true);
+
+		getChild<LLButton>("autoreplace_add_entry")->setEnabled(true);
+		disableReplacementEntry();		
+	}
+}
+
+void LLFloaterAutoReplaceSettings::enableReplacementEntry()
+{
+	LL_DEBUGS("AutoReplace")<<LL_ENDL;
+	mKeyword->setEnabled(true);
+	mReplacement->setEnabled(true);
+	getChild<LLButton>("autoreplace_save_entry")->setEnabled(true);
+	getChild<LLButton>("autoreplace_delete_entry")->setEnabled(true);
+}
+
+void LLFloaterAutoReplaceSettings::disableReplacementEntry()
+{
+	LL_DEBUGS("AutoReplace")<<LL_ENDL;
+	mPreviousKeyword.clear();
+	mKeyword->clear();
+	mKeyword->setEnabled(false);
+	mReplacement->clear();
+	mReplacement->setEnabled(false);
+	getChild<LLButton>("autoreplace_save_entry")->setEnabled(false);
+	getChild<LLButton>("autoreplace_delete_entry")->setEnabled(false);
+}
+
+// called when the global settings checkbox is changed
+void LLFloaterAutoReplaceSettings::onAutoReplaceToggled()
+{
+	// set our local copy of the flag, copied to the global preference in onOk
+	mEnabled = childGetValue("autoreplace_enable").asBoolean();
+	LL_DEBUGS("AutoReplace")<< "autoreplace_enable " << ( mEnabled ? "on" : "off" ) << LL_ENDL;
+}
+
+// called when the List Up button is pressed
+void LLFloaterAutoReplaceSettings::onListUp()
+{
+	S32 selectedRow = mListNames->getFirstSelectedIndex();
+	LLSD selectedName = mListNames->getSelectedValue().asString();
+
+	if ( mSettings.increaseListPriority(selectedName) )
+	{
+		updateListNames();
+		updateListNamesControls();
+	}
+	else
+	{
+		LL_WARNS("AutoReplace")
+			<< "invalid row ("<<selectedRow<<") selected '"<<selectedName<<"'"
+			<<LL_ENDL;
+	}
+}
+
+// called when the List Down button is pressed
+void LLFloaterAutoReplaceSettings::onListDown()
+{
+	S32 selectedRow = mListNames->getFirstSelectedIndex();
+	std::string selectedName = mListNames->getSelectedValue().asString();
+
+	if ( mSettings.decreaseListPriority(selectedName) )
+	{
+		updateListNames();
+		updateListNamesControls();
+	}
+	else
+	{
+		LL_WARNS("AutoReplace")
+			<< "invalid row ("<<selectedRow<<") selected '"<<selectedName<<"'"
+			<<LL_ENDL;
+	}
+}
+
+// called when the Delete Entry button is pressed
+void LLFloaterAutoReplaceSettings::onDeleteEntry()
+{
+    LLSD selectedRow = mReplacementsList->getSelectedValue();
+	if (selectedRow.isDefined())
+	{	
+		std::string keyword = selectedRow.asString();
+		mReplacementsList->deleteSelectedItems(); // delete from the control
+		mSettings.removeEntryFromList(keyword, mSelectedListName); // delete from the local settings copy
+		disableReplacementEntry(); // no selection active, so turn off the buttons
+	}
+}
+
+// called when the Import List button is pressed
+void LLFloaterAutoReplaceSettings::onImportList()
+{
+	LLFilePicker& picker = LLFilePicker::instance();
+	if( picker.getOpenFile( LLFilePicker::FFLOAD_XML) )
+	{
+		llifstream file;
+		file.open(picker.getFirstFile().c_str());
+		LLSD newList;
+		if (file.is_open())
+		{
+			LLSDSerialize::fromXMLDocument(newList, file);
+		}
+		file.close();
+
+		switch ( mSettings.addList(newList) )
+		{
+		case LLAutoReplaceSettings::AddListOk:
+			mSelectedListName = LLAutoReplaceSettings::getListName(newList);
+			
+			updateListNames();
+			updateListNamesControls();
+			updateReplacementsList();
+			break;
+
+		case LLAutoReplaceSettings::AddListDuplicateName:
+			{
+				std::string newName = LLAutoReplaceSettings::getListName(newList);
+				LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
+				LLSD newPayload;
+				newPayload["list"] = newList;
+				LLSD args;
+				args["DUPNAME"] = newName;
+	
+				LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
+										 boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2));
+			}
+			break;
+
+		case LLAutoReplaceSettings::AddListInvalidList:
+			LLNotificationsUtil::add("InvalidAutoReplaceList");
+			LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL;
+
+			mSelectedListName.clear();
+			updateListNames();
+			updateListNamesControls();
+			updateReplacementsList();
+			break;
+
+		default:
+			LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
+
+		}
+		
+	}
+	else
+	{
+		LL_DEBUGS("AutoReplace") << "file selection failed for import list" << LL_ENDL;
+	}		
+}
+
+void LLFloaterAutoReplaceSettings::onNewList()
+{
+	LLSD payload;
+	LLSD emptyList;
+	LLAutoReplaceSettings::createEmptyList(emptyList);
+	payload["list"] = emptyList;
+    LLSD args;
+	
+	LLNotificationsUtil::add("AddAutoReplaceList", args, payload,
+							 boost::bind(&LLFloaterAutoReplaceSettings::callbackNewListName, this, _1, _2));
+}
+
+bool LLFloaterAutoReplaceSettings::callbackNewListName(const LLSD& notification, const LLSD& response)
+{
+	LL_DEBUGS("AutoReplace")<<"called"<<LL_ENDL;
+	
+	LLSD newList = notification["payload"]["list"];
+
+	if ( response.has("listname") && response["listname"].isString() )
+	{
+		std::string newName = response["listname"].asString();
+		LLAutoReplaceSettings::setListName(newList, newName);
+
+		switch ( mSettings.addList(newList) )
+		{
+		case LLAutoReplaceSettings::AddListOk:
+			LL_INFOS("AutoReplace") << "added new list '"<<newName<<"'"<<LL_ENDL;
+			mSelectedListName = newName;
+			updateListNames();
+			updateListNamesControls();
+			updateReplacementsList();
+			break;
+
+		case LLAutoReplaceSettings::AddListDuplicateName:
+			{
+				LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
+				LLSD newPayload;
+				newPayload["list"] = notification["payload"]["list"];
+				LLSD args;
+				args["DUPNAME"] = newName;
+	
+				LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
+										 boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2));
+			}
+			break;
+
+		case LLAutoReplaceSettings::AddListInvalidList:
+			LLNotificationsUtil::add("InvalidAutoReplaceList");
+
+			mSelectedListName.clear();
+			updateListNames();
+			updateListNamesControls();
+			updateReplacementsList();
+			break;
+
+		default:
+			LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
+		}
+	}
+	else
+	{
+		LL_ERRS("AutoReplace") << "adding notification response" << LL_ENDL;
+	}
+	return false;
+}
+
+// callback for the RenameAutoReplaceList notification
+bool LLFloaterAutoReplaceSettings::callbackListNameConflict(const LLSD& notification, const LLSD& response)
+{
+	LLSD newList = notification["payload"]["list"];
+
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	switch ( option )
+	{
+	case 0:
+		// Replace current list
+		LL_INFOS("AutoReplace")<<"option 'replace current list' selected"<<LL_ENDL;
+		
+		break;
+
+	case 1:
+		// Use New Name
+		LL_INFOS("AutoReplace")<<"option 'use new name' selected"<<LL_ENDL;
+		callbackNewListName(notification, response);
+		break;
+
+	default:
+		LL_ERRS("AutoReplace")<<"invalid selected option "<<option<<LL_ENDL;
+	}
+
+	return false;
+}
+
+void LLFloaterAutoReplaceSettings::onDeleteList()
+{
+	std::string listName= mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
+	mSettings.removeReplacementList(listName); // remove from the copy of settings
+	mReplacementsList->deleteSelectedItems();   // remove from the scrolling list
+
+	mSelectedListName.clear();
+	updateListNames();
+	updateListNamesControls();
+	updateReplacementsList();
+}
+
+void LLFloaterAutoReplaceSettings::onExportList()
+{
+	std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
+	const LLSD* list = mSettings.exportList(listName);
+	std::string listFileName = listName + ".xml";
+	LLFilePicker& picker = LLFilePicker::instance();
+	if( picker.getSaveFile( LLFilePicker::FFSAVE_XML, listFileName) )
+	{
+		llofstream file;
+		file.open(picker.getFirstFile().c_str());
+		LLSDSerialize::toPrettyXML(*list, file);
+		file.close();
+	}
+}
+
+void LLFloaterAutoReplaceSettings::onAddEntry()
+{
+	mPreviousKeyword.clear();
+	mReplacementsList->deselectAllItems(false /* don't call commit */);
+	mKeyword->clear();
+	mReplacement->clear();
+	enableReplacementEntry();
+	mKeyword->setFocus(true);
+}
+
+void LLFloaterAutoReplaceSettings::onSaveEntry()
+{
+	LL_DEBUGS("AutoReplace")<<"called"<<LL_ENDL;
+	
+	if ( ! mPreviousKeyword.empty() )
+	{
+		// delete any existing value for the key that was editted
+		LL_INFOS("AutoReplace")
+			<< "list '" << mSelectedListName << "' "
+			<< "removed '" << mPreviousKeyword
+			<< "'" << LL_ENDL;
+		mSettings.removeEntryFromList( mPreviousKeyword, mSelectedListName );
+	}
+
+	LLWString keyword     = mKeyword->getWText();
+	LLWString replacement = mReplacement->getWText();
+	if ( mSettings.addEntryToList(keyword, replacement, mSelectedListName) )
+	{
+		// insert the new keyword->replacement pair
+		LL_INFOS("AutoReplace")
+			<< "list '" << mSelectedListName << "' "
+			<< "added '" << wstring_to_utf8str(keyword)
+			<< "' -> '" << wstring_to_utf8str(replacement)
+			<< "'" << LL_ENDL;
+
+		updateReplacementsList();
+	}
+	else
+	{
+		LLNotificationsUtil::add("InvalidAutoReplaceEntry");
+		LL_WARNS("AutoReplace")<<"invalid entry "
+							   << "keyword '" << wstring_to_utf8str(keyword)
+							   << "' replacement '" << wstring_to_utf8str(replacement)
+							   << "'" << LL_ENDL;
+	}
+}
+
+void LLFloaterAutoReplaceSettings::onCancel()
+{
+	cleanUp();
+	closeFloater(false /* not quitting */);
+}
+
+void LLFloaterAutoReplaceSettings::onSaveChanges()
+{
+	// put our local copy of the settings into the active copy
+	LLAutoReplace::getInstance()->setSettings( mSettings );
+	// save our local copy of the global feature enable/disable value
+	gSavedSettings.setBOOL("AutoReplace", mEnabled);
+	cleanUp();
+	closeFloater(false /* not quitting */);
+}
+
+void LLFloaterAutoReplaceSettings::cleanUp()
+{
+
+}
+
+bool LLFloaterAutoReplaceSettings::selectedListIsFirst()
+{
+	bool isFirst = false;
+	
+	if (!mSelectedListName.empty())
+	{
+		LLSD lists = mSettings.getListNames(); // an Array of Strings
+		LLSD first = lists.get(0);
+		if ( first.isString() && first.asString() == mSelectedListName )
+		{
+			isFirst = true;
+		}
+	}
+	return isFirst;
+}
+
+bool LLFloaterAutoReplaceSettings::selectedListIsLast()
+{
+	bool isLast = false;
+	
+	if (!mSelectedListName.empty())
+	{
+		LLSD last;
+		LLSD lists = mSettings.getListNames(); // an Array of Strings
+		for ( LLSD::array_const_iterator list = lists.beginArray(), listEnd = lists.endArray();
+			  list != listEnd;
+			  list++
+			 )
+		{
+			last = *list;
+		}
+		if ( last.isString() && last.asString() == mSelectedListName )
+		{
+			isLast = true;
+		}
+	}
+	return isLast;
+}
+
+/* TBD
+mOldText = getChild<LLLineEditor>("autoreplace_old_text");
+mNewText = getChild<LLLineEditor>("autoreplace_new_text");
+*/
diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..629aea3e3ce8d955b43d5953583af36ace84a1ac
--- /dev/null
+++ b/indra/newview/llfloaterautoreplacesettings.h
@@ -0,0 +1,117 @@
+/** 
+ * @file llfloaterautoreplacesettings.h
+ * @brief Auto Replace List floater
+ * @copyright Copyright (c) 2011 LordGregGreg Back
+ *
+ * $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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * 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
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATERAUTOREPLACESETTINGS_H
+#define LLFLOATERAUTOREPLACESETTINGS_H
+
+#include "llfloater.h"
+#include "llmediactrl.h"
+#include "llscrolllistctrl.h"
+#include "lllineeditor.h"
+
+#include "llviewerinventory.h"
+#include <boost/bind.hpp>
+#include "llautoreplace.h"
+
+class LLFloaterAutoReplaceSettings : public LLFloater
+{
+public:
+	LLFloaterAutoReplaceSettings(const LLSD& key);
+
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onClose(bool app_quitting);
+
+	void setData(void * data);
+
+private:
+
+	/** @{ @name Local Copies of Settings
+	 * These are populated in the postBuild method with the values
+	 * current when the floater is instantiated, and then either
+	 * discarded when Cancel is pressed, or copied back to the active
+	 * settings if Ok is pressed.
+	 */
+	bool mEnabled; ///< the global preference for AutoReplace 
+	LLAutoReplaceSettings mSettings; ///< settings being modified
+	/** @} */
+	
+	/// convenience variable - the name of the currently selected list (if any)
+	std::string       mSelectedListName;
+	/// the scrolling list of list names (one column, no headings, order manually controlled)
+	LLScrollListCtrl* mListNames;
+	/// the scroling list of keyword->replacement pairs
+	LLScrollListCtrl* mReplacementsList;
+
+	/// the keyword for the entry editing pane
+	LLLineEditor*     mKeyword;
+	/// saved keyword value
+	std::string       mPreviousKeyword;
+	/// the replacement for the entry editing pane
+	LLLineEditor*     mReplacement;
+	
+	/// callback for when the feature enable/disable checkbox changes
+	void onAutoReplaceToggled();
+	/// callback for when an entry in the list of list names is selected
+	void onSelectList();
+
+	void onImportList();
+	void onExportList();
+	void onNewList();
+	void onDeleteList();
+
+	void onListUp();
+	void onListDown();
+
+	void onSelectEntry();
+	void onAddEntry();
+	void onDeleteEntry();
+	void onSaveEntry();
+
+	void onSaveChanges();
+	void onCancel();
+
+	/// updates the contents of the mListNames
+	void updateListNames();
+	/// updates the controls associated with mListNames (depends on whether a name is selected or not)
+	void updateListNamesControls();
+	/// updates the contents of the mReplacementsList
+	void updateReplacementsList();
+	/// enables the components that should only be active when a keyword is selected
+	void enableReplacementEntry();
+	/// disables the components that should only be active when a keyword is selected
+	void disableReplacementEntry();
+
+	/// called from the AddAutoReplaceList notification dialog
+	bool callbackNewListName(const LLSD& notification, const LLSD& response);
+	/// called from the RenameAutoReplaceList notification dialog
+	bool callbackListNameConflict(const LLSD& notification, const LLSD& response);
+
+	bool selectedListIsFirst();
+	bool selectedListIsLast();
+
+	void cleanUp();
+};
+
+#endif  // LLFLOATERAUTOREPLACESETTINGS_H
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index ac33a05f425a1d36064d2efd5d2989489bf9d314..fa0ad20fdb09a310f5170f68f0513f321cc4e83c 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1124,9 +1124,13 @@ BOOL	LLPreviewAnimation::render()
 		LLVertexBuffer::unbind();
 		LLGLDepthTest gls_depth(GL_TRUE);
 
-		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
-		avatarp->dirtyMesh();
-		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
+		LLFace* face = avatarp->mDrawable->getFace(0);
+		if (face)
+		{
+			LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+			avatarp->dirtyMesh();
+			avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
+		}
 	}
 
 	gGL.color4f(1,1,1,1);
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 92ee8ddac6a54dc94d8519b1d787fd481c9bead9..6b2492d92758096e08d7427ecd41f55736b5e515 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -704,9 +704,13 @@ BOOL LLImagePreviewAvatar::render()
 		// make sure alpha=0 shows avatar material color
 		LLGLDisable no_blend(GL_BLEND);
 
-		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
-		gPipeline.enableLightsPreview();
-		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
+		LLFace* face = avatarp->mDrawable->getFace(0);
+		if (face)
+		{
+			LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+			gPipeline.enableLightsPreview();
+			avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
+		}
 	}
 
 	gGL.popUIMatrix();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index ee18c95b34745f00afbb1bda96268608aa953f58..61da99fe3a5b1bf798b89c9c4655475f17273bd3 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1865,23 +1865,8 @@ BOOL LLPanelLandOptions::postBuild()
 	childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this);
 
 	
-	if (gAgent.getAgentAccess().isInTransition())
-	{
-		// during the AO transition, this combo has an Adult item.
-		// Post-transition, it goes away. We can remove this conditional
-		// after the transition and just use the "else" clause.
-		mCategoryCombo = getChild<LLComboBox>( "land category with adult");
-		childSetCommitCallback("land category with adult", onCommitAny, this);
-	}
-	else
-	{
-		// this is the code that should be preserved post-transition
-		// you could also change the XML to set visibility and enabled true.
-		mCategoryCombo = getChild<LLComboBox>( "land category");
-		childSetCommitCallback("land category", onCommitAny, this);
-	}
-	mCategoryCombo->setVisible(true);
-	mCategoryCombo->setEnabled(true);
+	mCategoryCombo = getChild<LLComboBox>( "land category");
+	childSetCommitCallback("land category", onCommitAny, this);
 	
 
 	mMatureCtrl = getChild<LLCheckBoxCtrl>( "MatureCheck");
@@ -1901,6 +1886,7 @@ BOOL LLPanelLandOptions::postBuild()
 		mSnapshotCtrl->setCommitCallback( onCommitAny, this );
 		mSnapshotCtrl->setAllowNoTexture ( TRUE );
 		mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+		mSnapshotCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
 		mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
 	}
 	else
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 7448f2bb2a9fc5ade568d00f43c4ba45de0a393f..0a5171245ae1a08dfacce8ec60f1943258382780 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -396,7 +396,6 @@ mCalculateBtn(NULL)
 	sInstance = this;
 	mLastMouseX = 0;
 	mLastMouseY = 0;
-	mGLName = 0;
 	mStatusLock = new LLMutex(NULL);
 	mModelPreview = NULL;
 
@@ -538,11 +537,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
 		delete mModelPreview;
 	}
 
-	if (mGLName)
-	{
-		LLImageGL::deleteTextures(1, &mGLName );
-	}
-
 	delete mStatusLock;
 	mStatusLock = NULL;
 }
@@ -5053,15 +5047,7 @@ BOOL LLModelPreview::render()
 
 	LLRect preview_rect;
 
-	LLFloaterModelWizard* floater_wizard = dynamic_cast<LLFloaterModelWizard*>(mFMP);
-	if (floater_wizard)
-	{
-		preview_rect = floater_wizard->getPreviewRect();
-	}
-	else
-	{
-		preview_rect = mFMP->getChildView("preview_panel")->getRect();
-	}
+	preview_rect = mFMP->getChildView("preview_panel")->getRect();
 
 	F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight();
 
@@ -5605,7 +5591,6 @@ void LLModelPreview::setPreviewLOD(S32 lod)
 		combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
 		mFMP->childSetText("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]);
 
-		// the wizard has three lod drop downs
 		LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2");
 		combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
 		
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 64324854a55e82415ce91c0f8afb1d8498cc5f21..ab319c30d5e89ccfd8e613b9b24f5a2f9e0316f8 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -30,12 +30,12 @@
 #include "llfloaternamedesc.h"
 
 #include "lldynamictexture.h"
-#include "llfloatermodelwizard.h"
 #include "llquaternion.h"
 #include "llmeshrepository.h"
 #include "llmodel.h"
 #include "llthread.h"
 #include "llviewermenufile.h"
+#include "llfloatermodeluploadbase.h"
 
 class LLComboBox;
 class LLJoint;
@@ -256,7 +256,6 @@ class LLFloaterModelPreview : public LLFloaterModelUploadBase
 	S32				mLastMouseX;
 	S32				mLastMouseY;
 	LLRect			mPreviewRect;
-	U32				mGLName;
 	static S32		sUploadAmount;
 	
 	std::set<LLPointer<DecompRequest> > mCurRequest;
@@ -390,9 +389,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
  protected:
 	friend class LLModelLoader;
 	friend class LLFloaterModelPreview;
-	friend class LLFloaterModelWizard;
 	friend class LLFloaterModelPreview::DecompRequest;
-	friend class LLFloaterModelWizard::DecompRequest;
 	friend class LLPhysicsDecomp;
 
 	LLFloater*  mFMP;
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
deleted file mode 100644
index b517b78e5a9d2ae0c5ed7fe73f9299bf37f7cb78..0000000000000000000000000000000000000000
--- a/indra/newview/llfloatermodelwizard.cpp
+++ /dev/null
@@ -1,795 +0,0 @@
-/** 
- * @file llfloatermodelwizard.cpp
- * @author Leyla Farazha
- * @brief Implementation of the LLFloaterModelWizard class.
- *
- * $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 "llbutton.h"
-#include "lldrawable.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llfloater.h"
-#include "llfloatermodelwizard.h"
-#include "llfloatermodelpreview.h"
-#include "llfloaterreg.h"
-#include "llsliderctrl.h"
-#include "lltoolmgr.h"
-#include "llviewerwindow.h"
-
-LLFloaterModelWizard* LLFloaterModelWizard::sInstance = NULL;
-
-static	const std::string stateNames[]={
-	"choose_file",
-	"optimize",
-	"physics",
-	"review",
-	"upload"};
-
-static void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible);
-
-LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key)
-	: LLFloaterModelUploadBase(key)
-	 ,mRecalculateGeometryBtn(NULL)
-	 ,mRecalculatePhysicsBtn(NULL)
-	 ,mRecalculatingPhysicsBtn(NULL)
-	 ,mCalculateWeightsBtn(NULL)
-	 ,mCalculatingWeightsBtn(NULL)
-	 ,mChooseFilePreviewPanel(NULL)
-	 ,mOptimizePreviewPanel(NULL)
-	 ,mPhysicsPreviewPanel(NULL)
-{
-	mLastEnabledState = CHOOSE_FILE;
-	sInstance = this;
-
-	mCommitCallbackRegistrar.add("Wizard.Choose", boost::bind(&LLFloaterModelWizard::setState, this, CHOOSE_FILE));
-	mCommitCallbackRegistrar.add("Wizard.Optimize", boost::bind(&LLFloaterModelWizard::setState, this, OPTIMIZE));
-	mCommitCallbackRegistrar.add("Wizard.Physics", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS));
-	mCommitCallbackRegistrar.add("Wizard.Review", boost::bind(&LLFloaterModelWizard::setState, this, REVIEW));
-	mCommitCallbackRegistrar.add("Wizard.Upload", boost::bind(&LLFloaterModelWizard::setState, this, UPLOAD));
-}
-LLFloaterModelWizard::~LLFloaterModelWizard()
-{
-	sInstance = NULL;
-}
-void LLFloaterModelWizard::setState(int state)
-{
-
-	mState = state;
-
-	for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t)
-	{
-		LLView *view = getChildView(stateNames[t]+"_panel");
-		if (view) 
-		{
-			view->setVisible(state == (int) t ? TRUE : FALSE);
-		}
-	}
-
-	LLView* current_preview_panel = NULL;
-
-	if (state == CHOOSE_FILE)
-	{
-		mModelPreview->mViewOption["show_physics"] = false;
-
-		current_preview_panel = mChooseFilePreviewPanel;
-
-		getChildView("close")->setVisible(false);
-		getChildView("back")->setVisible(true);
-		getChildView("back")->setEnabled(false);
-		getChildView("next")->setVisible(true);
-		getChildView("upload")->setVisible(false);
-		getChildView("cancel")->setVisible(true);
-		mCalculateWeightsBtn->setVisible(false);
-		mCalculatingWeightsBtn->setVisible(false);
-	}
-
-	if (state == OPTIMIZE)
-	{
-		if (mLastEnabledState < state)
-		{			
-			mModelPreview->genLODs(-1);
-		}
-
-		mModelPreview->mViewOption["show_physics"] = false;
-
-		current_preview_panel = mOptimizePreviewPanel;
-
-		getChildView("back")->setVisible(true);
-		getChildView("back")->setEnabled(true);
-		getChildView("close")->setVisible(false);
-		getChildView("next")->setVisible(true);
-		getChildView("upload")->setVisible(false);
-		getChildView("cancel")->setVisible(true);
-		mCalculateWeightsBtn->setVisible(false);
-		mCalculatingWeightsBtn->setVisible(false);
-	}
-
-	if (state == PHYSICS)
-	{
-		if (mLastEnabledState < state)
-		{
-			mModelPreview->setPhysicsFromLOD(1);
-
-			// Trigger the recalculate physics when first entering
-			// the Physics step.
-			onClickRecalculatePhysics();
-		}
-
-		mModelPreview->mViewOption["show_physics"] = true;
-
-		current_preview_panel = mPhysicsPreviewPanel;
-
-		getChildView("next")->setVisible(false);
-		getChildView("upload")->setVisible(false);
-		getChildView("close")->setVisible(false);
-		getChildView("back")->setVisible(true);
-		getChildView("back")->setEnabled(true);
-		getChildView("cancel")->setVisible(true);
-		mCalculateWeightsBtn->setVisible(true);
-		mCalculatingWeightsBtn->setVisible(false);
-	}
-
-	if (state == REVIEW)
-	{
-		
-		mModelPreview->mViewOption["show_physics"] = false;
-
-		getChildView("close")->setVisible(false);
-		getChildView("next")->setVisible(false);
-		getChildView("back")->setVisible(true);
-		getChildView("back")->setEnabled(true);
-		getChildView("upload")->setVisible(true);
-		getChildView("cancel")->setVisible(true);
-		mCalculateWeightsBtn->setVisible(false);
-		mCalculatingWeightsBtn->setVisible(false);
-	}
-
-	if (state == UPLOAD)
-	{
-		getChildView("close")->setVisible(true);
-		getChildView("next")->setVisible(false);
-		getChildView("back")->setVisible(false);
-		getChildView("upload")->setVisible(false);
-		getChildView("cancel")->setVisible(false);
-		mCalculateWeightsBtn->setVisible(false);
-		mCalculatingWeightsBtn->setVisible(false);
-	}
-
-	if (current_preview_panel)
-	{
-		LLRect rect;
-		current_preview_panel->localRectToOtherView(current_preview_panel->getLocalRect(), &rect, this);
-
-		// Reduce the preview rect by 1 px to fit the borders
-		rect.stretch(-1);
-
-		if (rect != mPreviewRect)
-		{
-			mPreviewRect = rect;
-			mModelPreview->refresh();
-		}
-	}
-	updateButtons();
-}
-
-
-
-void LLFloaterModelWizard::updateButtons()
-{
-	if (mLastEnabledState < mState)
-	{
-		mLastEnabledState = mState;
-	}
-
-	for(size_t i=0; i<LL_ARRAY_SIZE(stateNames); ++i)
-	{
-		LLButton *button = getChild<LLButton>(stateNames[i]+"_btn");
-
-		if (i == mState)
-		{
-			button->setEnabled(TRUE);
-			button->setToggleState(TRUE);
-		}
-		else if (i <= mLastEnabledState)
-		{
-			button->setEnabled(TRUE);
-			button->setToggleState(FALSE);
-		}
-		else
-		{
-			button->setEnabled(FALSE);
-		}
-	}
-}
-
-void LLFloaterModelWizard::onClickSwitchToAdvanced()
-{
-	LLFloaterModelPreview* floater_preview = LLFloaterReg::getTypedInstance<LLFloaterModelPreview>("upload_model");
-	if (!floater_preview)
-	{
-		llwarns << "FLoater model preview not found." << llendl;
-		return;
-	}
-
-	// Open floater model preview
-	floater_preview->openFloater();
-
-	// Close the wizard
-	closeFloater();
-
-	std::string filename = getChild<LLUICtrl>("lod_file")->getValue().asString();
-	if (!filename.empty())
-	{
-		// Re-load the model to the floater model preview if it has been loaded
-		// into the wizard.
-		floater_preview->loadModel(3, filename);
-	}
-}
-
-void LLFloaterModelWizard::onClickRecalculateGeometry()
-{
-	S32 val = getChild<LLUICtrl>("accuracy_slider")->getValue().asInteger();
-
-	mModelPreview->genLODs(-1, NUM_LOD - val);
-
-	mModelPreview->refresh();
-}
-
-void LLFloaterModelWizard::onClickRecalculatePhysics()
-{
-	// Hide the "Recalculate physics" button and show the "Recalculating..."
-	// button instead.
-	swap_controls(mRecalculatePhysicsBtn, mRecalculatingPhysicsBtn, false);
-
-	executePhysicsStage("Decompose");
-}
-
-void LLFloaterModelWizard::onClickCalculateUploadFee()
-{
-	swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, false);
-
-	mModelPreview->rebuildUploadData();
-
-	mUploadModelUrl.clear();
-
-	gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
-			true, false, false, mUploadModelUrl, false, getWholeModelFeeObserverHandle());
-}
-
-void LLFloaterModelWizard::loadModel()
-{
-	 mModelPreview->mLoading = TRUE;
-	
-	(new LLMeshFilePicker(mModelPreview, 3))->getFile();
-}
-
-void LLFloaterModelWizard::onClickCancel()
-{
-	closeFloater();
-}
-
-void LLFloaterModelWizard::onClickBack()
-{
-	setState(llmax((int) CHOOSE_FILE, mState-1));
-}
-
-void LLFloaterModelWizard::onClickNext()
-{
-	setState(llmin((int) UPLOAD, mState+1));
-}
-
-bool LLFloaterModelWizard::onEnableNext()
-{
-	return true;
-}
-
-bool LLFloaterModelWizard::onEnableBack()
-{
-	return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// handleMouseDown()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	if (mPreviewRect.pointInRect(x, y))
-	{
-		bringToFront( x, y );
-		gFocusMgr.setMouseCapture(this);
-		gViewerWindow->hideCursor();
-		mLastMouseX = x;
-		mLastMouseY = y;
-		return TRUE;
-	}
-	
-	return LLFloater::handleMouseDown(x, y, mask);
-}
-
-//-----------------------------------------------------------------------------
-// handleMouseUp()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleMouseUp(S32 x, S32 y, MASK mask)
-{
-	gFocusMgr.setMouseCapture(FALSE);
-	gViewerWindow->showCursor();
-	return LLFloater::handleMouseUp(x, y, mask);
-}
-
-//-----------------------------------------------------------------------------
-// handleHover()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleHover	(S32 x, S32 y, MASK mask)
-{
-	MASK local_mask = mask & ~MASK_ALT;
-	
-	if (mModelPreview && hasMouseCapture())
-	{
-		if (local_mask == MASK_PAN)
-		{
-			// pan here
-			mModelPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
-		}
-		else if (local_mask == MASK_ORBIT)
-		{
-			F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
-			F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
-			
-			mModelPreview->rotate(yaw_radians, pitch_radians);
-		}
-		else 
-		{
-			
-			F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
-			F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
-			
-			mModelPreview->rotate(yaw_radians, 0.f);
-			mModelPreview->zoom(zoom_amt);
-		}
-		
-		
-		mModelPreview->refresh();
-		
-		LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY);
-	}
-	
-	if (!mPreviewRect.pointInRect(x, y) || !mModelPreview)
-	{
-		return LLFloater::handleHover(x, y, mask);
-	}
-	else if (local_mask == MASK_ORBIT)
-	{
-		gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
-	}
-	else if (local_mask == MASK_PAN)
-	{
-		gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
-	}
-	else
-	{
-		gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
-	}
-	
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// handleScrollWheel()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks)
-{
-	if (mPreviewRect.pointInRect(x, y) && mModelPreview)
-	{
-		mModelPreview->zoom((F32)clicks * -0.2f);
-		mModelPreview->refresh();
-	}
-	
-	return TRUE;
-}
-
-
-void LLFloaterModelWizard::initDecompControls()
-{
-	LLSD key;
-
-	static const LLCDStageData* stage = NULL;
-	static S32 stage_count = 0;
-
-	if (!stage && LLConvexDecomposition::getInstance() != NULL)
-	{
-		stage_count = LLConvexDecomposition::getInstance()->getStages(&stage);
-	}
-
-	static const LLCDParam* param = NULL;
-	static S32 param_count = 0;
-	if (!param && LLConvexDecomposition::getInstance() != NULL)
-	{
-		param_count = LLConvexDecomposition::getInstance()->getParameters(&param);
-	}
-
-	for (S32 j = stage_count-1; j >= 0; --j)
-	{
-		gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j;
-		// protected against stub by stage_count being 0 for stub above
-		LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
-
-		for (S32 i = 0; i < param_count; ++i)
-		{
-			if (param[i].mStage != j)
-			{
-				continue;
-			}
-
-			std::string name(param[i].mName ? param[i].mName : "");
-			std::string description(param[i].mDescription ? param[i].mDescription : "");
-
-			if (param[i].mType == LLCDParam::LLCD_FLOAT)
-			{
-				mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
-			}
-			else if (param[i].mType == LLCDParam::LLCD_INTEGER)
-			{
-				mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
-			}
-			else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
-			{
-				mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
-			}
-			else if (param[i].mType == LLCDParam::LLCD_ENUM)
-			{
-				mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
-			}
-		}
-	}
-
-	mDecompParams["Simplify Method"] = 0; // set it to retain %
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onPermissionsReceived(const LLSD& result)
-{
-	std::string upload_status = result["mesh_upload_status"].asString();
-	// BAP HACK: handle "" for case that  MeshUploadFlag cap is broken.
-	mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status));
-
-	getChildView("warning_label")->setVisible(!mHasUploadPerm);
-	getChildView("warning_text")->setVisible(!mHasUploadPerm);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::setPermissonsErrorStatus(U32 status, const std::string& reason)
-{
-	llwarns << "LLFloaterModelWizard::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl;
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
-{
-	swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true);
-
-	// Enable the "Upload" buton if we have calculated the upload fee
-	// and have the permission to upload.
-	getChildView("upload")->setEnabled(mHasUploadPerm);
-
-	mUploadModelUrl = upload_url;
-
-	S32 fee = result["upload_price"].asInteger();
-	childSetTextArg("review_fee", "[FEE]", llformat("%d", fee));
-	childSetTextArg("charged_fee", "[FEE]", llformat("%d", fee));
-
-	setState(REVIEW);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason)
-{
-	swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true);
-
-	// Disable the "Review" step if it has been previously enabled.
-	modelChangedCallback();
-
-	llwarns << "LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl;
-
-	setState(PHYSICS);
-}
-
-/*virtual*/ 
-void LLFloaterModelWizard::onModelUploadSuccess() 
-{
-	// success!
-	setState(UPLOAD);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onModelUploadFailure()
-{
-	// Failure. Make the user recalculate fees
-	setState(PHYSICS);
-	// Disable the "Review" step if it has been previously enabled.
-	if (mLastEnabledState > PHYSICS)
-	{
-		 mLastEnabledState = PHYSICS;
-	}
-
-	updateButtons();
-}
-
-//static
-void LLFloaterModelWizard::executePhysicsStage(std::string stage_name)
-{
-	if (sInstance)
-	{
-		// Invert the slider value so that "performance" end is giving the least detailed physics,
-		// and the "accuracy" end is giving the most detailed physics
-		F64 physics_accuracy = 1 - sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal();
-
-		sInstance->mDecompParams["Retain%"] = physics_accuracy;
-
-		if (!sInstance->mCurRequest.empty())
-		{
-			llinfos << "Decomposition request still pending." << llendl;
-			return;
-		}
-
-		if (sInstance->mModelPreview)
-		{
-			for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i)
-			{
-				LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i];
-				DecompRequest* request = new DecompRequest(stage_name, mdl);
-				if(request->isValid())
-				{
-					sInstance->mCurRequest.insert(request);
-					gMeshRepo.mDecompThread->submitRequest(request);
-				}				
-			}
-		}
-	}
-}
-
-LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
-{
-	mStage = stage;
-	mContinue = 1;
-	mModel = mdl;
-	mDecompID = &mdl->mDecompID;
-	mParams = sInstance->mDecompParams;
-
-	//copy out positions and indices
-	assignData(mdl) ;	
-}
-
-
-S32 LLFloaterModelWizard::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
-{
-	setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
-
-	return mContinue;
-}
-
-void LLFloaterModelWizard::DecompRequest::completed()
-{ //called from the main thread
-	mModel->setConvexHullDecomposition(mHull);
-
-	if (sInstance)
-	{
-		if (sInstance->mModelPreview)
-		{
-			sInstance->mModelPreview->mDirty = true;
-			LLFloaterModelWizard::sInstance->mModelPreview->refresh();
-		}
-
-		sInstance->mCurRequest.erase(this);
-	}
-
-	if (mStage == "Decompose")
-	{
-		executePhysicsStage("Simplify");
-	}
-	else
-	{
-		// Decomp request is complete so we can enable the "Recalculate physics" button again.
-		swap_controls(sInstance->mRecalculatePhysicsBtn, sInstance->mRecalculatingPhysicsBtn, true);
-	}
-}
-
-
-BOOL LLFloaterModelWizard::postBuild()
-{
-	childSetValue("import_scale", (F32) 0.67335826);
-
-	getChild<LLUICtrl>("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this));
-	//getChild<LLUICtrl>("lod_file")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this));
-	getChild<LLUICtrl>("cancel")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this));
-	getChild<LLUICtrl>("close")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this));
-	getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickBack, this));
-	getChild<LLUICtrl>("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this));
-	getChild<LLUICtrl>("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
-	getChild<LLUICtrl>("preview_lod_combo2")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
-	getChild<LLUICtrl>("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this));
-	getChild<LLUICtrl>("switch_to_advanced")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickSwitchToAdvanced, this));
-
-	mRecalculateGeometryBtn = getChild<LLButton>("recalculate_geometry_btn");
-	mRecalculateGeometryBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculateGeometry, this));
-
-	mRecalculatePhysicsBtn = getChild<LLButton>("recalculate_physics_btn");
-	mRecalculatePhysicsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculatePhysics, this));
-
-	mRecalculatingPhysicsBtn = getChild<LLButton>("recalculating_physics_btn");
-
-	mCalculateWeightsBtn = getChild<LLButton>("calculate");
-	mCalculateWeightsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCalculateUploadFee, this));
-
-	mCalculatingWeightsBtn = getChild<LLButton>("calculating");
-
-	mChooseFilePreviewPanel = getChild<LLView>("choose_file_preview_panel");
-	mOptimizePreviewPanel = getChild<LLView>("optimize_preview_panel");
-	mPhysicsPreviewPanel = getChild<LLView>("physics_preview_panel");
-
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	
-	enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this));
-	enable_registrar.add("Back.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableBack, this));
-	
-	mModelPreview = new LLModelPreview(512, 512, this);
-	mModelPreview->setPreviewTarget(16.f);
-	mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelWizard::setDetails, this, _1, _2, _3, _4, _5));
-	mModelPreview->setModelLoadedCallback(boost::bind(&LLFloaterModelWizard::modelLoadedCallback, this));
-	mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelWizard::modelChangedCallback, this));
-	mModelPreview->mViewOption["show_textures"] = true;
-
-	center();
-
-	setState(CHOOSE_FILE);
-
-	childSetTextArg("import_dimensions", "[X]", LLStringUtil::null);
-	childSetTextArg("import_dimensions", "[Y]", LLStringUtil::null);
-	childSetTextArg("import_dimensions", "[Z]", LLStringUtil::null);
-
-	initDecompControls();
-
-	requestAgentUploadPermissions();
-
-	return TRUE;
-}
-
-
-void LLFloaterModelWizard::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
-{
-	// iterate through all the panels, setting the dimensions
-	for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t)
-	{
-		LLPanel *panel = getChild<LLPanel>(stateNames[t]+"_panel");
-		if (panel) 
-		{
-			panel->childSetText("dimension_x", llformat("%.1f", x));
-			panel->childSetText("dimension_y", llformat("%.1f", y));
-			panel->childSetText("dimension_z", llformat("%.1f", z));
-		}
-	}
-
-	childSetTextArg("review_prim_equiv", "[EQUIV]", llformat("%d", mModelPreview->mResourceCost));
-}
-
-void LLFloaterModelWizard::modelLoadedCallback()
-{
-	mLastEnabledState = CHOOSE_FILE;
-	updateButtons();
-}
-
-void LLFloaterModelWizard::modelChangedCallback()
-{
-	// Don't allow to proceed to the "Review" step if the model has changed
-	// but the new upload fee hasn't been calculated yet.
-	if (mLastEnabledState > PHYSICS)
-	{
-		 mLastEnabledState = PHYSICS;
-	}
-
-	getChildView("upload")->setEnabled(false);
-
-	updateButtons();
-}
-
-void LLFloaterModelWizard::onUpload()
-{	
-	mModelPreview->rebuildUploadData();
-	
-	gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, 
-						  true, false, false, mUploadModelUrl, true,
-						  LLHandle<LLWholeModelFeeObserver>(), getWholeModelUploadObserverHandle());
-}
-
-void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl)
-{
-	if (!mModelPreview)
-	{
-		return;
-	}
-	
-	S32 which_mode = 0;
-	
-	LLComboBox* combo = (LLComboBox*) ctrl;
-	
-	which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order
-
-	mModelPreview->setPreviewLOD(which_mode);
-}
-
-void LLFloaterModelWizard::refresh()
-{
-	if (mState == CHOOSE_FILE)
-	{
-		bool model_loaded = false;
-
-		if (mModelPreview && mModelPreview->getLoadState() == LLModelLoader::DONE)
-		{
-			model_loaded = true;
-		}
-		
-		getChildView("next")->setEnabled(model_loaded);
-	}
-}
-
-void LLFloaterModelWizard::draw()
-{
-	refresh();
-
-	LLFloater::draw();
-
-	if (mModelPreview && mState < REVIEW)
-	{
-		mModelPreview->update();
-
-		gGL.color3f(1.f, 1.f, 1.f);
-		
-		gGL.getTexUnit(0)->bind(mModelPreview);
-		
-		gGL.begin( LLRender::QUADS );
-		{
-			gGL.texCoord2f(0.f, 1.f);
-			gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop);
-			gGL.texCoord2f(0.f, 0.f);
-			gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
-			gGL.texCoord2f(1.f, 0.f);
-			gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom);
-			gGL.texCoord2f(1.f, 1.f);
-			gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop);
-		}
-		gGL.end();
-		
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	}
-}
-
-// static
-void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible)
-{
-	first_ctrl->setVisible(first_ctr_visible);
-	second_ctrl->setVisible(!first_ctr_visible);
-}
diff --git a/indra/newview/llfloatermodelwizard.h b/indra/newview/llfloatermodelwizard.h
deleted file mode 100644
index db9b60577709f2519713a78e9c72850dff383a0a..0000000000000000000000000000000000000000
--- a/indra/newview/llfloatermodelwizard.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/** 
- * @file llfloatermodelwizard.h
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LLFLOATERMODELWIZARD_H
-#define LLFLOATERMODELWIZARD_H
-
-
-#include "llmeshrepository.h"
-#include "llmodel.h"
-#include "llthread.h"
-#include "llfloatermodeluploadbase.h"
-
-
-class LLModelPreview;
-
-
-class LLFloaterModelWizard : public LLFloaterModelUploadBase
-{
-public:
-	
-	class DecompRequest : public LLPhysicsDecomp::Request
-	{
-	public:
-		S32 mContinue;
-		LLPointer<LLModel> mModel;
-		
-		DecompRequest(const std::string& stage, LLModel* mdl);
-		virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
-		virtual void completed();
-		
-	};
-	
-	static LLFloaterModelWizard* sInstance;
-
-	LLFloaterModelWizard(const LLSD& key);
-	virtual ~LLFloaterModelWizard();
-	/*virtual*/	BOOL	postBuild();
-	void			draw();
-	void            refresh();
-	
-	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-	BOOL handleMouseUp(S32 x, S32 y, MASK mask);
-	BOOL handleHover(S32 x, S32 y, MASK mask);
-	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
-
-	void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
-	void modelLoadedCallback();
-	void modelChangedCallback();
-	void initDecompControls();
-	
-	// shows warning message if agent has no permissions to upload model
-	/*virtual*/ void onPermissionsReceived(const LLSD& result);
-
-	// called when error occurs during permissions request
-	/*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
-
-	/*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url);
-
-	/*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
-
-	/*virtual*/ void onModelUploadSuccess();
-
-	/*virtual*/ void onModelUploadFailure();
-
-	const LLRect& getPreviewRect() const { return mPreviewRect; }
-
-	LLPhysicsDecomp::decomp_params mDecompParams;
-	std::set<LLPointer<DecompRequest> > mCurRequest;
-	std::string mStatusMessage;
-	static void executePhysicsStage(std::string stage_name);
-
-private:
-	enum EWizardState
-	{
-		CHOOSE_FILE = 0,
-		OPTIMIZE,
-		PHYSICS,
-		REVIEW,
-		UPLOAD
-	};
-
-	void setState(int state);
-	void updateButtons();
-	void onClickSwitchToAdvanced();
-	void onClickRecalculateGeometry();
-	void onClickRecalculatePhysics();
-	void onClickCalculateUploadFee();
-	void onClickCancel();
-	void onClickBack();
-	void onClickNext();
-	bool onEnableNext();
-	bool onEnableBack();
-	void loadModel();
-	void onPreviewLODCommit(LLUICtrl*);
-	void onUpload();
-
-	LLModelPreview*	mModelPreview;
-	LLRect			mPreviewRect;
-	int mState;
-
-	S32				mLastMouseX;
-	S32				mLastMouseY;
-
-	U32			    mLastEnabledState;
-
-	LLButton*		mRecalculateGeometryBtn;
-	LLButton*		mRecalculatePhysicsBtn;
-	LLButton*		mRecalculatingPhysicsBtn;
-	LLButton*		mCalculateWeightsBtn;
-	LLButton*		mCalculatingWeightsBtn;
-
-	LLView*		mChooseFilePreviewPanel;
-	LLView*		mOptimizePreviewPanel;
-	LLView*		mPhysicsPreviewPanel;
-};
-
-
-#endif
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 173b0e538cab14114b54b4116b0cf97fb2e9fd87..5edd920c708b2bf9afe82bb7bdd2e0c97e377828 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -35,7 +35,7 @@
 #include "llfloaterpreference.h"
 
 #include "message.h"
-
+#include "llfloaterautoreplacesettings.h"
 #include "llagent.h"
 #include "llavatarconstants.h"
 #include "llcheckboxctrl.h"
@@ -346,7 +346,9 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.BlockList",				boost::bind(&LLFloaterPreference::onClickBlockList, this));
 	mCommitCallbackRegistrar.add("Pref.Proxy",					boost::bind(&LLFloaterPreference::onClickProxySettings, this));
 	mCommitCallbackRegistrar.add("Pref.TranslationSettings",	boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
-	
+	mCommitCallbackRegistrar.add("Pref.AutoReplace",            boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+	mCommitCallbackRegistrar.add("Pref.SpellChecker",           boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
+
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
 	mCommitCallbackRegistrar.add("Pref.ClickActionChange",				boost::bind(&LLFloaterPreference::onClickActionChange, this));
@@ -354,7 +356,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
-
+	
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
 }
 
@@ -435,6 +437,8 @@ BOOL LLFloaterPreference::postBuild()
 
 	gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));
 
+	gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
+
 	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 	if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
 		tabcontainer->selectFirstTab();
@@ -604,6 +608,9 @@ void LLFloaterPreference::cancel()
 	// hide translation settings floater
 	LLFloaterReg::hideInstance("prefs_translation");
 	
+	// hide translation settings floater
+	LLFloaterReg::hideInstance("prefs_autoreplace");
+	
 	// cancel hardware menu
 	LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
 	if (hardware_settings)
@@ -931,7 +938,6 @@ void LLFloaterPreference::refreshSkin(void* data)
 	self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
 }
 
-
 void LLFloaterPreference::buildPopupLists()
 {
 	LLScrollListCtrl& disabled_popups =
@@ -1515,6 +1521,16 @@ void LLFloaterPreference::onClickTranslationSettings()
 	LLFloaterReg::showInstance("prefs_translation");
 }
 
+void LLFloaterPreference::onClickAutoReplace()
+{
+	LLFloaterReg::showInstance("prefs_autoreplace");
+}
+
+void LLFloaterPreference::onClickSpellChecker()
+{
+		LLFloaterReg::showInstance("prefs_spellchecker");
+}
+
 void LLFloaterPreference::onClickActionChange()
 {
 	mClickActionDirty = true;
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index ec5994e91754afa5a071a478179dac2843b8e565..b71f7c647b180951ff144f4a8dc490ea13033eba 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -157,6 +157,8 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void onClickBlockList();
 	void onClickProxySettings();
 	void onClickTranslationSettings();
+	void onClickAutoReplace();
+	void onClickSpellChecker();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
 	
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ecdd1191813b9f202988479a57bd9694d19a86f
--- /dev/null
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -0,0 +1,491 @@
+/** 
+ * @file llfloaterspellchecksettings.h
+ * @brief Spell checker settings floater
+ *
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llcombobox.h"
+#include "llfilepicker.h"
+#include "llfloaterreg.h"
+#include "llfloaterspellchecksettings.h"
+#include "llscrolllistctrl.h"
+#include "llsdserialize.h"
+#include "llspellcheck.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llnotificationsutil.h"
+
+#include <boost/algorithm/string.hpp>
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSpellCheckerSettings
+///----------------------------------------------------------------------------
+LLFloaterSpellCheckerSettings::LLFloaterSpellCheckerSettings(const LLSD& key)
+	: LLFloater(key)
+{
+}
+
+void LLFloaterSpellCheckerSettings::draw()
+{
+	LLFloater::draw();
+
+	std::vector<LLScrollListItem*> sel_items = getChild<LLScrollListCtrl>("spellcheck_available_list")->getAllSelected();
+	bool enable_remove = !sel_items.empty();
+	for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+	{
+		enable_remove &= LLSpellChecker::canRemoveDictionary((*sel_it)->getValue().asString());
+	}
+	getChild<LLUICtrl>("spellcheck_remove_btn")->setEnabled(enable_remove);
+}
+
+BOOL LLFloaterSpellCheckerSettings::postBuild(void)
+{
+	gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false));
+	LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange, this));
+	getChild<LLUICtrl>("spellcheck_remove_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnRemove, this));
+	getChild<LLUICtrl>("spellcheck_import_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnImport, this));
+	getChild<LLUICtrl>("spellcheck_main_combo")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false));
+	getChild<LLUICtrl>("spellcheck_moveleft_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_active_list", "spellcheck_available_list"));
+	getChild<LLUICtrl>("spellcheck_moveright_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_available_list", "spellcheck_active_list"));
+	center();
+	return true;
+}
+
+void LLFloaterSpellCheckerSettings::onBtnImport()
+{
+	LLFloaterReg::showInstance("prefs_spellchecker_import");
+}
+
+void LLFloaterSpellCheckerSettings::onBtnMove(const std::string& from, const std::string& to)
+{
+	LLScrollListCtrl* from_ctrl = findChild<LLScrollListCtrl>(from);
+	LLScrollListCtrl* to_ctrl = findChild<LLScrollListCtrl>(to);
+
+	LLSD row;
+	row["columns"][0]["column"] = "name";
+
+	std::vector<LLScrollListItem*> sel_items = from_ctrl->getAllSelected();
+	std::vector<LLScrollListItem*>::const_iterator sel_it;
+	for ( sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+	{
+		row["value"] = (*sel_it)->getValue();
+		row["columns"][0]["value"] = (*sel_it)->getColumn(0)->getValue();
+		to_ctrl->addElement(row);
+		to_ctrl->setSelectedByValue( (*sel_it)->getValue(), true );
+	}
+	from_ctrl->deleteSelectedItems();
+}
+
+void LLFloaterSpellCheckerSettings::onClose(bool app_quitting)
+{
+	if (app_quitting)
+	{
+		// don't save anything
+		return;
+	}
+	LLFloaterReg::hideInstance("prefs_spellchecker_import");
+	
+	std::list<std::string> list_dict;
+
+	LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo");
+	const std::string dict_name = dict_combo->getSelectedItemLabel();
+	if (!dict_name.empty())
+	{
+		list_dict.push_back(dict_name);
+
+		LLScrollListCtrl* list_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list");
+		std::vector<LLScrollListItem*> list_items = list_ctrl->getAllData();
+		for (std::vector<LLScrollListItem*>::const_iterator item_it = list_items.begin(); item_it != list_items.end(); ++item_it)
+		{
+			const std::string language = (*item_it)->getValue().asString();
+			if (LLSpellChecker::hasDictionary(language, true))
+			{
+				list_dict.push_back(language);
+			}
+		}
+	}
+	gSavedSettings.setString("SpellCheckDictionary", boost::join(list_dict, ","));
+}
+
+void LLFloaterSpellCheckerSettings::onOpen(const LLSD& key)
+{
+	refreshDictionaries(true);
+}
+
+void LLFloaterSpellCheckerSettings::onBtnRemove()
+{
+	std::vector<LLScrollListItem*> sel_items = getChild<LLScrollListCtrl>("spellcheck_available_list")->getAllSelected();
+	for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+	{
+		LLSpellChecker::instance().removeDictionary((*sel_it)->getValue().asString());
+	}
+}
+
+void LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange()
+{
+	refreshDictionaries(true);
+}
+
+void LLFloaterSpellCheckerSettings::refreshDictionaries(bool from_settings)
+{
+	bool enabled = gSavedSettings.getBOOL("SpellCheck");
+	getChild<LLUICtrl>("spellcheck_moveleft_btn")->setEnabled(enabled);
+	getChild<LLUICtrl>("spellcheck_moveright_btn")->setEnabled(enabled);
+
+	// Populate the dictionary combobox
+	LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo");
+	std::string dict_cur = dict_combo->getSelectedItemLabel();
+	if ((dict_cur.empty() || from_settings) && (LLSpellChecker::getUseSpellCheck()))
+	{
+		dict_cur = LLSpellChecker::instance().getPrimaryDictionary();
+	}
+	dict_combo->clearRows();
+
+	const LLSD& dict_map = LLSpellChecker::getDictionaryMap();
+	if (dict_map.size())
+	{
+		for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
+		{
+			const LLSD& dict = *dict_it;
+			if ( (dict["installed"].asBoolean()) && (dict["is_primary"].asBoolean()) && (dict.has("language")) )
+			{
+				dict_combo->add(dict["language"].asString());
+			}
+		}
+		if (!dict_combo->selectByValue(dict_cur))
+		{
+			dict_combo->clear();
+		}
+	}
+	dict_combo->sortByName();
+	dict_combo->setEnabled(enabled);
+
+	// Populate the available and active dictionary list
+	LLScrollListCtrl* avail_ctrl = findChild<LLScrollListCtrl>("spellcheck_available_list");
+	LLScrollListCtrl* active_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list");
+
+	LLSpellChecker::dict_list_t active_list;
+	if ( ((!avail_ctrl->getItemCount()) && (!active_ctrl->getItemCount())) || (from_settings) )
+	{
+		if (LLSpellChecker::getUseSpellCheck())
+		{
+			active_list = LLSpellChecker::instance().getSecondaryDictionaries();
+		}
+	}
+	else
+	{
+		std::vector<LLScrollListItem*> active_items = active_ctrl->getAllData();
+		for (std::vector<LLScrollListItem*>::const_iterator item_it = active_items.begin(); item_it != active_items.end(); ++item_it)
+		{
+			std::string dict = (*item_it)->getValue().asString();
+			if (dict_cur != dict)
+			{
+				active_list.push_back(dict);
+			}
+		}
+	}
+
+	LLSD row;
+	row["columns"][0]["column"] = "name";
+
+	active_ctrl->clearRows();
+	active_ctrl->setEnabled(enabled);
+	for (LLSpellChecker::dict_list_t::const_iterator it = active_list.begin(); it != active_list.end(); ++it)
+	{
+		const std::string language = *it;
+		const LLSD dict = LLSpellChecker::getDictionaryData(language);
+		row["value"] = language;
+		row["columns"][0]["value"] = (!dict["user_installed"].asBoolean()) ? language : language + " " + LLTrans::getString("UserDictionary");
+		active_ctrl->addElement(row);
+	}
+	active_ctrl->sortByColumnIndex(0, true);
+	active_list.push_back(dict_cur);
+
+	avail_ctrl->clearRows();
+	avail_ctrl->setEnabled(enabled);
+	for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
+	{
+		const LLSD& dict = *dict_it;
+		const std::string language = dict["language"].asString();
+		if ( (dict["installed"].asBoolean()) && (active_list.end() == std::find(active_list.begin(), active_list.end(), language)) )
+		{
+			row["value"] = language;
+			row["columns"][0]["value"] = (!dict["user_installed"].asBoolean()) ? language : language + " " + LLTrans::getString("UserDictionary");
+			avail_ctrl->addElement(row);
+		}
+	}
+	avail_ctrl->sortByColumnIndex(0, true);
+}
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSpellCheckerImport
+///----------------------------------------------------------------------------
+LLFloaterSpellCheckerImport::LLFloaterSpellCheckerImport(const LLSD& key)
+	: LLFloater(key)
+{
+}
+
+BOOL LLFloaterSpellCheckerImport::postBuild(void)
+{
+	getChild<LLUICtrl>("dictionary_path_browse")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnBrowse, this));
+	getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnOK, this));
+	getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnCancel, this));
+	center();
+	return true;
+}
+
+void LLFloaterSpellCheckerImport::onBtnBrowse()
+{
+	LLFilePicker& file_picker = LLFilePicker::instance();
+	if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_DICTIONARY))
+	{
+		return;
+	}
+
+	std::string filepath = file_picker.getFirstFile();
+
+	const std::string extension = gDirUtilp->getExtension(filepath);
+	if ("xcu" == extension)
+	{
+		filepath = parseXcuFile(filepath);
+		if (filepath.empty())
+		{
+			return;
+		}
+	}
+
+	getChild<LLUICtrl>("dictionary_path")->setValue(filepath);
+	
+	mDictionaryDir = gDirUtilp->getDirName(filepath);
+	mDictionaryBasename = gDirUtilp->getBaseFileName(filepath, true);
+	getChild<LLUICtrl>("dictionary_name")->setValue(mDictionaryBasename);
+}
+
+void LLFloaterSpellCheckerImport::onBtnCancel()
+{
+	closeFloater(false);
+}
+
+void LLFloaterSpellCheckerImport::onBtnOK()
+{
+	const std::string dict_dic = mDictionaryDir + gDirUtilp->getDirDelimiter() + mDictionaryBasename + ".dic";
+	const std::string dict_aff = mDictionaryDir + gDirUtilp->getDirDelimiter() + mDictionaryBasename + ".aff";
+	std::string dict_language = getChild<LLUICtrl>("dictionary_language")->getValue().asString();
+	LLStringUtil::trim(dict_language);
+
+	bool imported = false;
+	if (   dict_language.empty()
+		|| mDictionaryDir.empty()
+		|| mDictionaryBasename.empty()
+		|| ! gDirUtilp->fileExists(dict_dic)
+		)
+	{
+		LLNotificationsUtil::add("SpellingDictImportRequired");
+	}
+	else
+	{
+		std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic";
+		if ( copyFile( dict_dic, settings_dic ) )
+		{
+			if (gDirUtilp->fileExists(dict_aff))
+			{
+				std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff";
+				if (copyFile( dict_aff, settings_aff ))
+				{
+					imported = true;
+				}
+				else
+				{
+					LLSD args = LLSD::emptyMap();
+					args["FROM_NAME"] = dict_aff;
+					args["TO_NAME"] = settings_aff;
+					LLNotificationsUtil::add("SpellingDictImportFailed", args);
+				}
+			}
+			else
+			{
+				LLSD args = LLSD::emptyMap();
+				args["DIC_NAME"] = dict_dic;
+				LLNotificationsUtil::add("SpellingDictIsSecondary", args);
+
+				imported = true;
+			}
+		}
+		else
+		{
+			LLSD args = LLSD::emptyMap();
+			args["FROM_NAME"] = dict_dic;
+			args["TO_NAME"] = settings_dic;
+			LLNotificationsUtil::add("SpellingDictImportFailed", args);
+		}
+	}
+
+	if ( imported )
+	{
+		LLSD custom_dict_info;
+		custom_dict_info["is_primary"] = (bool)gDirUtilp->fileExists(dict_aff);
+		custom_dict_info["name"] = mDictionaryBasename;
+		custom_dict_info["language"] = dict_language;
+
+		LLSD custom_dict_map;
+		llifstream custom_file_in(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml");
+		if (custom_file_in.is_open())
+		{
+			LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file_in);
+			custom_file_in.close();
+		}
+	
+		LLSD::array_iterator it = custom_dict_map.beginArray();
+		for (; it != custom_dict_map.endArray(); ++it)
+		{
+			LLSD& dict_info = *it;
+			if (dict_info["name"].asString() == mDictionaryBasename)
+			{
+				dict_info = custom_dict_info;
+				break;
+			}
+		}
+		if (custom_dict_map.endArray() == it)
+		{
+			custom_dict_map.append(custom_dict_info);
+		}
+
+		llofstream custom_file_out(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml", std::ios::trunc);
+		if (custom_file_out.is_open())
+		{
+			LLSDSerialize::toPrettyXML(custom_dict_map, custom_file_out);
+			custom_file_out.close();
+		}
+
+		LLSpellChecker::refreshDictionaryMap();
+	}
+
+	closeFloater(false);
+}
+
+bool LLFloaterSpellCheckerImport::copyFile(const std::string from, const std::string to)
+{
+	bool copied = false;
+	LLFILE* in = LLFile::fopen(from, "rb");		/* Flawfinder: ignore */	 	
+	if (in)	 	
+	{	 	
+		LLFILE* out = LLFile::fopen(to, "wb");		/* Flawfinder: ignore */
+		if (out)
+		{
+			char buf[16384];		/* Flawfinder: ignore */ 	
+			size_t readbytes;
+			bool write_ok = true;
+			while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
+			{
+				if (fwrite(buf, 1, readbytes, out) != readbytes)
+				{
+					LL_WARNS("SpellCheck") << "Short write" << LL_ENDL; 
+					write_ok = false;
+				}
+			}
+			if ( write_ok )
+			{
+				copied = true;
+			}
+			fclose(out);
+		}
+	}
+	fclose(in);
+	return copied;
+}
+
+std::string LLFloaterSpellCheckerImport::parseXcuFile(const std::string& file_path) const
+{
+	LLXMLNodePtr xml_root;
+	if ( (!LLUICtrlFactory::getLayeredXMLNode(file_path, xml_root)) || (xml_root.isNull()) )
+	{
+		return LLStringUtil::null;
+	}
+
+	// Bury down to the "Dictionaries" parent node
+	LLXMLNode* dict_node = NULL;
+	for (LLXMLNode* outer_node = xml_root->getFirstChild(); outer_node && !dict_node; outer_node = outer_node->getNextSibling())
+	{
+		std::string temp;
+		if ( (outer_node->getAttributeString("oor:name", temp)) && ("ServiceManager" == temp) )
+		{
+			for (LLXMLNode* inner_node = outer_node->getFirstChild(); inner_node && !dict_node; inner_node = inner_node->getNextSibling())
+			{
+				if ( (inner_node->getAttributeString("oor:name", temp)) && ("Dictionaries" == temp) )
+				{
+					dict_node = inner_node;
+					break;
+				}
+			}
+		}
+	}
+
+	if (dict_node)
+	{
+		// Iterate over all child nodes until we find one that has a <value>DICT_SPELL</value> node
+		for (LLXMLNode* outer_node = dict_node->getFirstChild(); outer_node; outer_node = outer_node->getNextSibling())
+		{
+			std::string temp;
+			LLXMLNodePtr location_node, format_node;
+			for (LLXMLNode* inner_node = outer_node->getFirstChild(); inner_node; inner_node = inner_node->getNextSibling())
+			{
+				if (inner_node->getAttributeString("oor:name", temp))
+				{
+					if ("Locations" == temp)
+					{
+						inner_node->getChild("value", location_node, false);
+					}
+					else if ("Format" == temp)
+					{
+						inner_node->getChild("value", format_node, false);
+					}
+				}
+			}
+			if ( (format_node.isNull()) || ("DICT_SPELL" != format_node->getValue()) || (location_node.isNull()) )
+			{
+				continue;
+			}
+
+			// Found a list of file locations, return the .dic (if present)
+			std::list<std::string> location_list;
+			boost::split(location_list, location_node->getValue(), boost::is_any_of(std::string(" ")));
+			for (std::list<std::string>::iterator it = location_list.begin(); it != location_list.end(); ++it)
+			{
+				std::string& location = *it;
+				if ("\\" != gDirUtilp->getDirDelimiter())
+					LLStringUtil::replaceString(location, "\\", gDirUtilp->getDirDelimiter());
+				else
+					LLStringUtil::replaceString(location, "/", gDirUtilp->getDirDelimiter());
+				LLStringUtil::replaceString(location, "%origin%", gDirUtilp->getDirName(file_path));
+				if ("dic" == gDirUtilp->getExtension(location))
+				{
+					return location;
+				}
+			}
+		}
+	}
+
+	return LLStringUtil::null;
+}
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..eded3a9133d0c8b751c34d3af31c878c80289ce3
--- /dev/null
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -0,0 +1,68 @@
+/** 
+ * @file llfloaterspellchecksettings.h
+ * @brief Spell checker settings floater
+ *
+* $LicenseInfo:firstyear=2011&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 LLFLOATERSPELLCHECKERSETTINGS_H
+#define LLFLOATERSPELLCHECKERSETTINGS_H
+
+#include "llfloater.h"
+
+class LLFloaterSpellCheckerSettings : public LLFloater
+{
+public:
+	LLFloaterSpellCheckerSettings(const LLSD& key);
+
+	/*virtual*/ void draw();
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
+
+protected:
+	void onBtnImport();
+	void onBtnMove(const std::string& from, const std::string& to);
+	void onBtnRemove();
+	void onSpellCheckSettingsChange();
+	void refreshDictionaries(bool from_settings);
+};
+
+class LLFloaterSpellCheckerImport : public LLFloater
+{
+public:
+	LLFloaterSpellCheckerImport(const LLSD& key);
+
+	/*virtual*/ BOOL postBuild();
+
+protected:
+	void onBtnBrowse();
+	void onBtnCancel();
+	void onBtnOK();
+	bool copyFile(const std::string from, const std::string to);
+	std::string parseXcuFile(const std::string& file_path) const;
+
+	std::string mDictionaryDir;
+	std::string mDictionaryBasename;
+};
+
+#endif  // LLFLOATERSPELLCHECKERSETTINGS_H
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 1fa194ab1918b41bb8d9a1c01ff1c1113ef2bf8c..9ce64a630fe883511ccd9eaac7fb3103feb91f9f 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -562,7 +562,6 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
 	{
 		width = scroll_rect.getWidth();
 	}
-
 	LLView::reshape(width, height, called_from_parent);
 	mReshapeSignal(mSelectedItems, FALSE);
 }
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f67464078b20d085aa6331608f69d1af2a8d6f32..63eedcdfeae4d849fcc2eaa3047c9d96c19a0cf3 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -56,7 +56,7 @@
 #include "llrootview.h"
 #include "llspeakers.h"
 #include "llviewerchat.h"
-
+#include "llautoreplace.h"
 
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id),
@@ -255,6 +255,8 @@ BOOL LLIMFloater::postBuild()
 	mInputEditor->setMaxTextLength(1023);
 	// enable line history support for instant message bar
 	mInputEditor->setEnableLineHistory(TRUE);
+	// *TODO Establish LineEditor with autoreplace callback
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
 
 	LLFontGL* font = LLViewerChat::getChatFont();
 	mInputEditor->setFont(font);	
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 8092f3bf36bbcfe7cf5898847b4532ca9dbe503a..6e23d7c70139e5ed863067121f224af7d68032ac 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -822,6 +822,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
 			{
 				parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
 				new_item->setParent(parent_id);
+				LLInventoryModel::update_list_t update;
+				LLInventoryModel::LLCategoryUpdate new_folder(parent_id, 1);
+				update.push_back(new_folder);
+				accountForUpdate(update);
+
 			}
 			item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, parent_id);
 			if(item_array)
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 3a88fbd96deab76c4a0a8811d5f5497071cc6f43..f8088d04b406c67deefc248fe960c79848801fa4 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -60,6 +60,7 @@
 #include "llworld.h"
 #include "llui.h"
 #include "pipeline.h"
+#include "llviewershadermgr.h"
 
 const S32 NUM_AXES = 3;
 const S32 MOUSE_DRAG_SLOP = 2;       // pixels
@@ -1580,7 +1581,11 @@ void LLManipTranslate::renderSnapGuides()
 					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
 					LLGLEnable stipple(GL_LINE_STIPPLE);
 					gGL.flush();
-					glLineStipple(1, 0x3333);
+
+					if (!LLGLSLShader::sNoFixedFunction)
+					{
+						glLineStipple(1, 0x3333);
+					}
 		
 					switch (mManipPart)
 					{
@@ -1645,17 +1650,28 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 											 LLQuaternion grid_rotation, 
 											 LLColor4 inner_color)
 {
-	if (!gSavedSettings.getBOOL("GridCrossSections"))
+	if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction)
 	{
 		return;
 	}
 	
+	
+	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+	
 	U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
 	U32 num_types = LL_ARRAY_SIZE(types);
 
 	GLuint stencil_mask = 0xFFFFFFFF;
 	//stencil in volumes
+
 	gGL.flush();
+
+	if (shader)
+	{
+		gClipProgram.bind();
+	}
+		
 	{
 		glStencilMask(stencil_mask);
 		glClearStencil(1);
@@ -1666,6 +1682,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 		glStencilFunc(GL_ALWAYS, 0, stencil_mask);
 		gGL.setColorMask(false, false);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
 		gGL.diffuseColor4f(1,1,1,1);
 
 		//setup clip plane
@@ -1675,10 +1692,12 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 			normal = -normal;
 		}
 		F32 d = -(selection_center * normal);
-		F64 plane[] = { normal.mV[0], normal.mV[1], normal.mV[2], d };
-		LLGLEnable clip(GL_CLIP_PLANE0);
-		glClipPlane(GL_CLIP_PLANE0, plane);
+		glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d );
+
+		gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane);
 
+		gClipProgram.uniform4fv("clip_plane", 1, plane.v);
+		
 		BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
 		BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
 		
@@ -1729,6 +1748,11 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 	F32 sz = mGridSizeMeters;
 	F32 tiles = sz;
 
+	if (shader)
+	{
+		shader->bind();
+	}
+
 	//draw volume/plane intersections
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index c899e8991e195360d0aa89cf7ed10408068f26a8..bc7f522848e8423c61efe10037ef7eb79d982797 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1659,7 +1659,7 @@ void LLMeshUploadThread::requestWholeModelFee()
 		mCurlRequest->process();
 		//sleep for 10ms to prevent eating a whole core
 		apr_sleep(10000);
-	} while (mCurlRequest->getQueued() > 0);
+	} while (!LLApp::isQuitting() && mCurlRequest->getQueued() > 0);
 
 	delete mCurlRequest;
 	mCurlRequest = NULL;
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 00ff81724cc12efd307a9715a102e1e1787b1326..f8f0f7d243688c497783935dfbe5cd052a4a67c2 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -52,6 +52,7 @@
 #include "lltranslate.h"
 
 #include "llresizehandle.h"
+#include "llautoreplace.h"
 
 S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
 
@@ -89,6 +90,7 @@ BOOL LLNearbyChatBar::postBuild()
 {
 	mChatBox = getChild<LLLineEditor>("chat_box");
 
+	mChatBox->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
 	mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
 	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
 	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7c6287967af3c1f5925a28488c3a6157e3dd4668..16c51138a9f21fd31fb32d4a638edc5dd844b7e2 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -128,6 +128,8 @@ const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
 						FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
 						SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
 						TELEPORT_OFFERED("TeleportOffered"),
+						TELEPORT_OFFERED_MATURITY_EXCEEDED("TeleportOffered_MaturityExceeded"),
+						TELEPORT_OFFERED_MATURITY_BLOCKED("TeleportOffered_MaturityBlocked"),
 						TELEPORT_OFFER_SENT("TeleportOfferSent"),
 						IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip");
 
@@ -149,6 +151,8 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
 			|| INVENTORY_DECLINED == notification->getName()
 			|| USER_GIVE_ITEM == notification->getName()
 			|| TELEPORT_OFFERED == notification->getName()
+			|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+			|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName()
 			|| TELEPORT_OFFER_SENT == notification->getName()
 			|| IM_SYSTEM_MESSAGE_TIP == notification->getName();
 }
@@ -169,7 +173,9 @@ bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
 {
 	return OFFER_FRIENDSHIP == notification->getName()
 			|| USER_GIVE_ITEM == notification->getName()
-			|| TELEPORT_OFFERED == notification->getName();
+			|| TELEPORT_OFFERED == notification->getName()
+			|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+			|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
 }
 
 // static
@@ -177,7 +183,9 @@ bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
 {
 	return OFFER_FRIENDSHIP == notification->getName()
 					|| USER_GIVE_ITEM == notification->getName()
-					|| TELEPORT_OFFERED == notification->getName();
+					|| TELEPORT_OFFERED == notification->getName()
+					|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+					|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
 }
 
 // static
@@ -185,7 +193,9 @@ bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification
 {
 	return OFFER_FRIENDSHIP == notification->getName()
 		|| USER_GIVE_ITEM == notification->getName()
-		|| TELEPORT_OFFERED == notification->getName();
+		|| TELEPORT_OFFERED == notification->getName()
+		|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+		|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
 }
 
 // static
@@ -212,7 +222,9 @@ bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
 
 	if(OFFER_FRIENDSHIP == notification->getName()
 		|| USER_GIVE_ITEM == notification->getName()
-		|| TELEPORT_OFFERED == notification->getName())
+		|| TELEPORT_OFFERED == notification->getName()
+		|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+		|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName())
 	{
 		// When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
 		return ! isIMFloaterOpened(notification);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 03404e816b11a2581e81707c1a39bf563787e36f..d58d6d536c0da5580cab4187b411af7989f0f6e2 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -574,6 +574,7 @@ static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const L
                 texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);
                 // Don't allow (no copy) or (notransfer) textures to be selected.
                 texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+                texture_ctrl->setDnDFilterPermMask(PERM_NONE);
                 texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
         }
 }
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7301b305b2d54182110e48c6caf68e360a47c379..3e298054466bbc367ce90cd60252ad9882270193 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -38,6 +38,7 @@
 #include "llfontgl.h"
 
 // project includes
+#include "llagentdata.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llcolorswatch.h"
@@ -46,6 +47,7 @@
 #include "llface.h"
 #include "lllineeditor.h"
 #include "llmediaentry.h"
+#include "llnotificationsutil.h"
 #include "llresmgr.h"
 #include "llselectmgr.h"
 #include "llspinctrl.h"
@@ -104,27 +106,11 @@ BOOL	LLPanelFace::postBuild()
 		mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
 		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
 		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+		mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
 		mTextureCtrl->setFollowsTop();
 		mTextureCtrl->setFollowsLeft();
-		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
-		mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
-		// Allow any texture to be used during non-immediate mode.
-		mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE);
-		LLAggregatePermissions texture_perms;
-		if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
-		{
-			BOOL can_copy = 
-				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || 
-				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
-			BOOL can_transfer = 
-				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || 
-				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
-			mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer);
-		}
-		else
-		{
-			mTextureCtrl->setCanApplyImmediately(FALSE);
-		}
+		mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+		mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
 	}
 
 	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
@@ -595,28 +581,6 @@ void LLPanelFace::getState()
 		}
 
 		
-		LLAggregatePermissions texture_perms;
-		if(texture_ctrl)
-		{
-// 			texture_ctrl->setValid( editable );
-		
-			if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
-			{
-				BOOL can_copy = 
-					texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || 
-					texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
-				BOOL can_transfer = 
-					texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || 
-					texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
-				texture_ctrl->setCanApplyImmediately(can_copy && can_transfer);
-			}
-			else
-			{
-				texture_ctrl->setCanApplyImmediately(FALSE);
-			}
-		}
-
-
 		// planar align
 		bool align_planar = false;
 		bool identical_planar_aligned = false;
@@ -1190,3 +1154,35 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
 	self->sendTextureInfo();
 }
 
+void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
+{
+	LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+	if (texture_ctrl)
+	{
+		LLUUID obj_owner_id;
+		std::string obj_owner_name;
+		LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+		LLSaleInfo sale_info;
+		LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+		bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
+		bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
+		bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
+		bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
+
+		if (can_copy && can_transfer)
+		{
+			texture_ctrl->setCanApply(true, true);
+			return;
+		}
+
+		// if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+		texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+		if (gSavedSettings.getBOOL("TextureLivePreview"))
+		{
+			LLNotificationsUtil::add("LivePreviewUnavailable");
+		}
+	}
+}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 42be9b257f9b0e21938d40a14214255dc72f4090..3b5a9b1398c8d0fb111abb67215f8664cf1735c8 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -91,6 +91,15 @@ class LLPanelFace : public LLPanel
 	static void		onClickAutoFix(void*);
 	static F32      valueGlow(LLViewerObject* object, S32 face);
 
+private:
+
+	/*
+	 * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.
+	 * If agent selects texture which is not allowed to be applied for the currently selected object,
+	 * all controls of the floater texture picker which allow to apply the texture will be disabled.
+	 */
+	void onTextureSelectionChanged(LLInventoryItem* itemp);
+
 };
 
 #endif
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index b3adfac8a246eb87737c567e4438220209cf3d76..26cd3ff1c19b509fe65cf726258b6bec772b6d96 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -85,6 +85,7 @@ BOOL LLPanelLandMedia::postBuild()
 	mMediaTextureCtrl->setCommitCallback( onCommitAny, this );
 	mMediaTextureCtrl->setAllowNoTexture ( TRUE );
 	mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+	mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
 	mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
 
 	mMediaAutoScaleCheck = getChild<LLCheckBoxCtrl>("media_auto_scale");
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index c01adc3c3562eb0c3deb2d9460c3ff51aa780ae8..a50d9074f7d9488e2742bfce5502ef672de48b72 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -176,7 +176,7 @@ void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
 {
 	// update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes
 	mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
-							gSavedSettings.getBOOL("MediaTentativeAutoPlay");							
+							gSavedSettings.getBOOL("MediaTentativeAutoPlay");
 }
 
 /*virtual*/
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 1f77e7a602e069fd5b0e761b69c9379c8a857265..7dfe529b73f373569d4adda1fe269ce83cd70816 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -245,6 +245,7 @@ BOOL	LLPanelObject::postBuild()
 		mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
 		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
 		mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+		mCtrlSculptTexture->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
 		// Allow any texture to be used during non-immediate mode.
 		mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
 		LLAggregatePermissions texture_perms;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index eec2c0a5211fac95f6fc372b6355c804574c1bdb..a55565909f3649a69c7b805395a67eebe269e0fc 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1508,6 +1508,49 @@ struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
 	}
 };
 
+void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
+{
+	if (!item)
+	{
+		return;
+	}
+	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
+
+	for (iterator iter = begin(); iter != end(); ++iter)
+	{
+		LLSelectNode* node = *iter;
+		LLViewerObject* object = (*iter)->getObject();
+		if (!object)
+		{
+			continue;
+		}
+
+		S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+		bool texture_copied = false;
+		for (S32 te = 0; te < num_tes; ++te)
+		{
+			if (node->isTESelected(te))
+			{
+				//(no-copy) textures must be moved to the object's inventory only once
+				// without making any copies
+				if (!texture_copied)
+				{
+					LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+					texture_copied = true;
+				}
+
+				// apply texture for the selected faces
+				LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+				object->setTEImage(te, image);
+				dialog_refresh_all();
+
+				// send the update to the simulator
+				object->sendTEUpdate();
+			}
+		}
+	}
+}
+
 //-----------------------------------------------------------------------------
 // selectionSetImage()
 //-----------------------------------------------------------------------------
@@ -1559,8 +1602,18 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
 			}
 			return true;
 		}
-	} setfunc(item, imageid);
-	getSelection()->applyToTEs(&setfunc);
+	};
+
+	if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+	{
+		getSelection()->applyNoCopyTextureToTEs(item);
+	}
+	else
+	{
+		f setfunc(item, imageid);
+		getSelection()->applyToTEs(&setfunc);
+	}
+
 
 	struct g : public LLSelectedObjectFunctor
 	{
@@ -5583,7 +5636,7 @@ void pushWireframe(LLDrawable* drawable)
 			for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
 			{
 				const LLVolumeFace& face = volume->getVolumeFace(i);
-				LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
+				LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
 			}
 		}
 
@@ -5610,7 +5663,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
 
 	if (shader)
 	{
-		gHighlightProgram.bind();
+		gDebugProgram.bind();
 	}
 
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 87ada5ac6b6cbe3acc9535519a0356343e2a1f4d..94606b9fba6739fc962fff86192fb9594459c505 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -307,6 +307,15 @@ class LLObjectSelection : public LLRefCount
 	bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
 	bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
 
+	/*
+	 * Used to apply (no-copy) textures to the selected object or
+	 * selected face/faces of the object.
+	 * This method moves (no-copy) texture to the object's inventory
+	 * and doesn't make copy of the texture for each face.
+	 * Then this only texture is used for all selected faces.
+	 */
+	void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+
 	ESelectType getSelectType() const { return mSelectType; }
 
 private:
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 8e62b79d7f21c8c4c9c11f7c402b1290e4e748b0..325a2d300453a0dce2dd4e22e2c5470576aa20ae 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -85,12 +85,32 @@ static F32 sCurMaxTexPriority = 1.f;
 
 class LLOcclusionQueryPool : public LLGLNamePool
 {
+public:
+	LLOcclusionQueryPool()
+	{
+		mCurQuery = 1;
+	}
+
 protected:
+
+	std::list<GLuint> mAvailableName;
+	GLuint mCurQuery;
+		
 	virtual GLuint allocateName()
 	{
-		GLuint name;
-		glGenQueriesARB(1, &name);
-		return name;
+		GLuint ret = 0;
+
+		if (!mAvailableName.empty())
+		{
+			ret = mAvailableName.front();
+			mAvailableName.pop_front();
+		}
+		else
+		{
+			ret = mCurQuery++;
+		}
+
+		return ret;
 	}
 
 	virtual void releaseName(GLuint name)
@@ -98,7 +118,8 @@ class LLOcclusionQueryPool : public LLGLNamePool
 #if LL_TRACK_PENDING_OCCLUSION_QUERIES
 		LLSpatialGroup::sPendingQueries.erase(name);
 #endif
-		glDeleteQueriesARB(1, &name);
+		llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end());
+		mAvailableName.push_back(name);
 	}
 };
 
@@ -259,79 +280,39 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
 	return (U8*) (sOcclusionIndices+cypher*8);
 }
 
-
-static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
-
-void LLSpatialGroup::buildOcclusion()
+//create a vertex buffer for efficiently rendering cubes
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
 {
-	//if (mOcclusionVerts.isNull())
-	{
-		mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 
-			LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
-		mOcclusionVerts->allocateBuffer(8, 64, true);
-	
-		LLStrider<U16> idx;
-		mOcclusionVerts->getIndexStrider(idx);
-		for (U32 i = 0; i < 64; i++)
-		{
-			*idx++ = sOcclusionIndices[i];
-		}
-	}
+	LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage);
 
-	LLVector4a fudge;
-	fudge.splat(SG_OCCLUSION_FUDGE);
-
-	LLVector4a r;
-	r.setAdd(mBounds[1], fudge);
+	ret->allocateBuffer(8, 64, true);
 
 	LLStrider<LLVector3> pos;
-	
-	{
-		LLFastTimer t(FTM_BUILD_OCCLUSION);
-		mOcclusionVerts->getVertexStrider(pos);
-	}
+	LLStrider<U16> idx;
 
-	{
-		LLVector4a* v = (LLVector4a*) pos.get();
+	ret->getVertexStrider(pos);
+	ret->getIndexStrider(idx);
 
-		const LLVector4a& c = mBounds[0];
-		const LLVector4a& s = r;
-		
-		static const LLVector4a octant[] =
-		{
-			LLVector4a(-1.f, -1.f, -1.f),
-			LLVector4a(-1.f, -1.f, 1.f),
-			LLVector4a(-1.f, 1.f, -1.f),
-			LLVector4a(-1.f, 1.f, 1.f),
-
-			LLVector4a(1.f, -1.f, -1.f),
-			LLVector4a(1.f, -1.f, 1.f),
-			LLVector4a(1.f, 1.f, -1.f),
-			LLVector4a(1.f, 1.f, 1.f),
-		};
-
-		//vertex positions are encoded so the 3 bits of their vertex index 
-		//correspond to their axis facing, with bit position 3,2,1 matching
-		//axis facing x,y,z, bit set meaning positive facing, bit clear 
-		//meaning negative facing
-		
-		for (S32 i = 0; i < 8; ++i)
-		{
-			LLVector4a p;
-			p.setMul(s, octant[i]);
-			p.add(c);
-			v[i] = p;
-		}
-	}
-	
+	pos[0] = LLVector3(-1,-1,-1);
+	pos[1] = LLVector3(-1,-1, 1);
+	pos[2] = LLVector3(-1, 1,-1);
+	pos[3] = LLVector3(-1, 1, 1);
+	pos[4] = LLVector3( 1,-1,-1);
+	pos[5] = LLVector3( 1,-1, 1);
+	pos[6] = LLVector3( 1, 1,-1);
+	pos[7] = LLVector3( 1, 1, 1);
+
+	for (U32 i = 0; i < 64; i++)
 	{
-		mOcclusionVerts->flush();
-		LLVertexBuffer::unbind();
+		idx[i] = sOcclusionIndices[i];
 	}
 
-	clearState(LLSpatialGroup::OCCLUSION_DIRTY);
+	ret->flush();
+
+	return ret;
 }
 
+static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
 
 BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group);
 
@@ -394,8 +375,6 @@ LLSpatialGroup::~LLSpatialGroup()
 		}
 	}
 
-	mOcclusionVerts = NULL;
-
 	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
 	clearDrawMap();
 	clearAtlasList() ;
@@ -687,6 +666,11 @@ void LLSpatialGroup::rebuildGeom()
 	if (!isDead())
 	{
 		mSpatialPartition->rebuildGeom(this);
+
+		if (isState(LLSpatialGroup::MESH_DIRTY))
+		{
+			gPipeline.markMeshDirty(this);
+		}
 	}
 }
 
@@ -699,6 +683,9 @@ void LLSpatialGroup::rebuildMesh()
 }
 
 static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_ADD_GEOMETRY_COUNT("Add Geometry");
+static LLFastTimer::DeclareTimer FTM_CREATE_VB("Create VB");
+static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry");
 
 void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
 {
@@ -720,27 +707,36 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
 	//get geometry count
 	U32 index_count = 0;
 	U32 vertex_count = 0;
-	
-	addGeometryCount(group, vertex_count, index_count);
+
+	{
+		LLFastTimer t(FTM_ADD_GEOMETRY_COUNT);
+		addGeometryCount(group, vertex_count, index_count);
+	}
 
 	if (vertex_count > 0 && index_count > 0)
 	{ //create vertex buffer containing volume geometry for this node
-		group->mBuilt = 1.f;
-		if (group->mVertexBuffer.isNull() ||
-			!group->mVertexBuffer->isWriteable() ||
-			(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
 		{
-			group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
-			group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
-			stop_glerror();
+			LLFastTimer t(FTM_CREATE_VB);
+			group->mBuilt = 1.f;
+			if (group->mVertexBuffer.isNull() ||
+				!group->mVertexBuffer->isWriteable() ||
+				(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
+			{
+				group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
+				group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
+				stop_glerror();
+			}
+			else
+			{
+				group->mVertexBuffer->resizeBuffer(vertex_count, index_count);
+				stop_glerror();
+			}
 		}
-		else
+
 		{
-			group->mVertexBuffer->resizeBuffer(vertex_count, index_count);
-			stop_glerror();
+			LLFastTimer t(FTM_GET_GEOMETRY);
+			getGeometry(group);
 		}
-		
-		getGeometry(group);
 	}
 	else
 	{
@@ -932,11 +928,6 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
 		setState(GEOM_DIRTY);
 		gPipeline.markRebuild(this, TRUE);
 	}
-
-	if (mOcclusionVerts.notNull())
-	{
-		setState(OCCLUSION_DIRTY);
-	}
 }
 
 class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler
@@ -1235,8 +1226,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
 		mVisible[i] = 0;
 	}
 
-	mOcclusionVerts = NULL;
-
 	mRadius = 1;
 	mPixelArea = 1024.f;
 }
@@ -1465,10 +1454,14 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo
 	unbound();
 }
 
-void LLSpatialGroup::destroyGL() 
+void LLSpatialGroup::destroyGL(bool keep_occlusion) 
 {
 	setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
-	gPipeline.markRebuild(this, TRUE);
+
+	if (!keep_occlusion)
+	{ //going to need a rebuild
+		gPipeline.markRebuild(this, TRUE);
+	}
 
 	mLastUpdateTime = gFrameTimeSeconds;
 	mVertexBuffer = NULL;
@@ -1476,16 +1469,18 @@ void LLSpatialGroup::destroyGL()
 
 	clearDrawMap();
 
-	for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+	if (!keep_occlusion)
 	{
-		if (mOcclusionQuery[i])
+		for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
 		{
-			sQueryPool.release(mOcclusionQuery[i]);
-			mOcclusionQuery[i] = 0;
+			if (mOcclusionQuery[i])
+			{
+				sQueryPool.release(mOcclusionQuery[i]);
+				mOcclusionQuery[i] = 0;
+			}
 		}
 	}
 
-	mOcclusionVerts = NULL;
 
 	for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
 	{
@@ -1493,7 +1488,10 @@ void LLSpatialGroup::destroyGL()
 		for (S32 j = 0; j < drawable->getNumFaces(); j++)
 		{
 			LLFace* facep = drawable->getFace(j);
-			facep->clearVertexBuffer();
+			if (facep)
+			{
+				facep->clearVertexBuffer();
+			}
 		}
 	}
 }
@@ -1556,15 +1554,13 @@ BOOL LLSpatialGroup::rebound()
 		mBounds[1].mul(0.5f);
 	}
 	
-	setState(OCCLUSION_DIRTY);
-	
 	clearState(DIRTY);
 
 	return TRUE;
 }
 
 static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait");
 
 void LLSpatialGroup::checkOcclusion()
 {
@@ -1584,7 +1580,9 @@ void LLSpatialGroup::checkOcclusion()
 			{
 				glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
 
-				if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+				static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion");
+
+				if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
 				{ //query was issued last frame, wait until it's available
 					S32 max_loop = 1024;
 					LLFastTimer t(FTM_OCCLUSION_WAIT);
@@ -1635,7 +1633,9 @@ void LLSpatialGroup::checkOcclusion()
 				else
 				{
 					assert_states_valid(this);
+					
 					setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
+					
 					assert_states_valid(this);
 				}
 
@@ -1690,12 +1690,6 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 						mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
 					}
 
-					if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
-					{
-						LLFastTimer t(FTM_OCCLUSION_BUILD);
-						buildOcclusion();
-					}
-					
 					// Depth clamp all water to avoid it being culled as a result of being
 					// behind the far clip plane, and in the case of edge water to avoid
 					// it being culled while still visible.
@@ -1726,10 +1720,13 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 							glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					
 						}
 					
-						{
-							LLFastTimer t(FTM_OCCLUSION_SET_BUFFER);
-							mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
-						}
+						LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+						llassert(shader);
+
+						shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr());
+						shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, 
+																 mBounds[1][1]+SG_OCCLUSION_FUDGE, 
+																 mBounds[1][2]+SG_OCCLUSION_FUDGE);
 
 						if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
 						{
@@ -1738,12 +1735,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 							LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
 							if (camera->getOrigin().isExactlyZero())
 							{ //origin is invalid, draw entire box
-								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
-								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
+								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
 							}
 							else
 							{
-								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
 							}
 						}
 						else
@@ -1751,12 +1748,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 							LLFastTimer t(FTM_OCCLUSION_DRAW);
 							if (camera->getOrigin().isExactlyZero())
 							{ //origin is invalid, draw entire box
-								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
-								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
+								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
 							}
 							else
 							{
-								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
 							}
 						}
 
@@ -2480,18 +2477,21 @@ void pushVerts(LLSpatialGroup* group, U32 mask)
 
 void pushVerts(LLFace* face, U32 mask)
 {
-	llassert(face->verify());
+	if (face)
+	{
+		llassert(face->verify());
 
-	LLVertexBuffer* buffer = face->getVertexBuffer();
+		LLVertexBuffer* buffer = face->getVertexBuffer();
 
-	if (buffer && (face->getGeomCount() >= 3))
-	{
-		buffer->setBuffer(mask);
-		U16 start = face->getGeomStart();
-		U16 end = start + face->getGeomCount()-1;
-		U32 count = face->getIndicesCount();
-		U16 offset = face->getIndicesStart();
-		buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+		if (buffer && (face->getGeomCount() >= 3))
+		{
+			buffer->setBuffer(mask);
+			U16 start = face->getGeomStart();
+			U16 end = start + face->getGeomCount()-1;
+			U32 count = face->getIndicesCount();
+			U16 offset = face->getIndicesStart();
+			buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+		}
 	}
 }
 
@@ -2628,7 +2628,7 @@ void renderOctree(LLSpatialGroup* group)
 				for (S32 j = 0; j < drawable->getNumFaces(); j++)
 				{
 					LLFace* face = drawable->getFace(j);
-					if (face->getVertexBuffer())
+					if (face && face->getVertexBuffer())
 					{
 						if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
 						{
@@ -2757,19 +2757,6 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 			gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
 			pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
 		}
-		/*else if (camera && group->mOcclusionVerts.notNull())
-		{
-			LLVertexBuffer::unbind();
-			group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
-			
-			gGL.diffuseColor4f(1.0f, 0.f, 0.f, 0.5f);
-			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
-			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-			
-			gGL.diffuseColor4f(1.0f, 1.f, 1.f, 1.0f);
-			group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
-			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-		}*/
 	}
 }
 
@@ -2999,15 +2986,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
 	for (S32 i = 0; i < drawable->getNumFaces(); i++)
 	{
 		LLFace* facep = drawable->getFace(i);
+		if (facep)
+		{
+			ext = facep->mExtents;
 
-		ext = facep->mExtents;
-
-		pos.setAdd(ext[0], ext[1]);
-		pos.mul(0.5f);
-		size.setSub(ext[1], ext[0]);
-		size.mul(0.5f);
+			pos.setAdd(ext[0], ext[1]);
+			pos.mul(0.5f);
+			size.setSub(ext[1], ext[0]);
+			size.mul(0.5f);
 		
-		drawBoxOutline(pos,size);
+			drawBoxOutline(pos,size);
+		}
 	}
 
 	//render drawable bounding box
@@ -3499,18 +3488,21 @@ void renderPhysicsShapes(LLSpatialGroup* group)
 				for (S32 i = 0; i < drawable->getNumFaces(); ++i)
 				{
 					LLFace* face = drawable->getFace(i);
-					LLVertexBuffer* buff = face->getVertexBuffer();
-					if (buff)
+					if (face)
 					{
-						glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+						LLVertexBuffer* buff = face->getVertexBuffer();
+						if (buff)
+						{
+							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
-						buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-						gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
-						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+							buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+							gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
+							buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
 									
-						gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
-						glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+							gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
+							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+							buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+						}
 					}
 				}
 			}
@@ -3534,6 +3526,7 @@ void renderTexturePriority(LLDrawable* drawable)
 		
 		//LLViewerTexture* imagep = facep->getTexture();
 		//if (imagep)
+		if (facep)
 		{
 				
 			//F32 vsize = imagep->mMaxVirtualSize;
@@ -3586,7 +3579,11 @@ void renderPoints(LLDrawable* drawablep)
 		gGL.diffuseColor3f(1,1,1);
 		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
 		{
-			gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
+			LLFace * face = drawablep->getFace(i);
+			if (face)
+			{
+				gGL.vertex3fv(face->mCenterLocal.mV);
+			}
 		}
 		gGL.end();
 	}
@@ -3767,7 +3764,11 @@ void renderLights(LLDrawable* drawablep)
 
 		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
 		{
-			pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
+			LLFace * face = drawablep->getFace(i);
+			if (face)
+			{
+				pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+			}
 		}
 
 		const LLVector4a* ext = drawablep->getSpatialExtents();
@@ -4169,18 +4170,21 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 				for (U32 i = 0; i < drawable->getNumFaces(); ++i)
 				{
 					LLFace* facep = drawable->getFace(i);
-					U8 index = facep->getTextureIndex();
-					if (facep->mDrawInfo)
+					if (facep)
 					{
-						if (index < 255)
+						U8 index = facep->getTextureIndex();
+						if (facep->mDrawInfo)
 						{
-							if (facep->mDrawInfo->mTextureList.size() <= index)
-							{
-								llerrs << "Face texture index out of bounds." << llendl;
-							}
-							else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+							if (index < 255)
 							{
-								llerrs << "Face texture index incorrect." << llendl;
+								if (facep->mDrawInfo->mTextureList.size() <= index)
+								{
+									llerrs << "Face texture index out of bounds." << llendl;
+								}
+								else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+								{
+									llerrs << "Face texture index incorrect." << llendl;
+								}
 							}
 						}
 					}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 1a93145cc5f4ccb2a896f1aaa7a0d5914d50cd78..f0e4f15a83b579c855acc68c0c706905653965cf 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -263,11 +263,10 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable>
 		SKIP_FRUSTUM_CHECK		= 0x00000020,
 		IN_IMAGE_QUEUE			= 0x00000040,
 		IMAGE_DIRTY				= 0x00000080,
-		OCCLUSION_DIRTY			= 0x00000100,
-		MESH_DIRTY				= 0x00000200,
-		NEW_DRAWINFO			= 0x00000400,
-		IN_BUILD_Q1				= 0x00000800,
-		IN_BUILD_Q2				= 0x00001000,
+		MESH_DIRTY				= 0x00000100,
+		NEW_DRAWINFO			= 0x00000200,
+		IN_BUILD_Q1				= 0x00000400,
+		IN_BUILD_Q2				= 0x00000800,
 		STATE_MASK				= 0x0000FFFF,
 	} eSpatialState;
 
@@ -313,10 +312,9 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable>
 	BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
 	void unbound();
 	BOOL rebound();
-	void buildOcclusion(); //rebuild mOcclusionVerts
 	void checkOcclusion(); //read back last occlusion query (if any)
 	void doOcclusion(LLCamera* camera); //issue occlusion query
-	void destroyGL();
+	void destroyGL(bool keep_occlusion = false);
 	
 	void updateDistance(LLCamera& camera);
 	BOOL needsUpdate();
@@ -415,7 +413,6 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable>
 	LLSpatialPartition* mSpatialPartition;
 	
 	LLPointer<LLVertexBuffer> mVertexBuffer;
-	LLPointer<LLVertexBuffer> mOcclusionVerts;
 	GLuint					mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
 
 	U32 mBufferUsage;
@@ -657,6 +654,7 @@ class LLParticlePartition : public LLSpatialPartition
 {
 public:
 	LLParticlePartition();
+	virtual void rebuildGeom(LLSpatialGroup* group);
 	virtual void getGeometry(LLSpatialGroup* group);
 	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
 	virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
@@ -671,10 +669,14 @@ class LLHUDParticlePartition : public LLParticlePartition
 };
 
 //spatial partition for grass (implemented in LLVOGrass.cpp)
-class LLGrassPartition : public LLParticlePartition
+class LLGrassPartition : public LLSpatialPartition
 {
 public:
 	LLGrassPartition();
+	virtual void getGeometry(LLSpatialGroup* group);
+	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
+protected:
+	U32 mRenderPass;
 };
 
 //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6b0fc26db7a62d2e9a660591b19105462e60ca4a..ee7a234bbe8b4a869eab2d765ecef487d6eaec4a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -740,6 +740,7 @@ bool idle_startup()
 		{
 			display_startup();
 			initialize_edit_menu();
+			initialize_spellcheck_menu();
 			display_startup();
 			init_menus();
 			display_startup();
@@ -3215,17 +3216,6 @@ bool process_login_success_response()
 
 		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
 	}
-	// During the AO transition, this flag will be true. Then the flag will
-	// go away. After the AO transition, this code and all the code that
-	// uses it can be deleted.
-	text = response["ao_transition"].asString();
-	if (!text.empty())
-	{
-		if (text == "1")
-		{
-			gAgent.setAOTransition();
-		}
-	}
 
 	text = response["start_location"].asString();
 	if(!text.empty()) 
diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp
index d2e4b0173246a3ec04e1b812da026e91e8917ffc..f8c1bca8aed1097696f9609a5ce6040487ad2683 100644
--- a/indra/newview/lltextureatlas.cpp
+++ b/indra/newview/lltextureatlas.cpp
@@ -116,7 +116,6 @@ LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_
 		return 0 ;
 	}
 
-	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE);
 	glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h,
 						mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData());
 	
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ed9faa070601ea72801cee172df5fecdd9bd58fb..6703ef4a41d8aa3a7735e456c4cd857e5fa3b6c4 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -97,6 +97,7 @@ class LLFloaterTexturePicker : public LLFloater
 		LLTextureCtrl* owner,
 		const std::string& label,
 		PermissionMask immediate_filter_perm_mask,
+		PermissionMask dnd_filter_perm_mask,
 		PermissionMask non_immediate_filter_perm_mask,
 		BOOL can_apply_immediately,
 		LLUIImagePtr fallback_image_name);
@@ -134,6 +135,9 @@ class LLFloaterTexturePicker : public LLFloater
 	
 	void onFilterEdit(const std::string& search_string );
 	
+	void setCanApply(bool can_preview, bool can_apply);
+	void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;}
+
 	static void		onBtnSetToDefault( void* userdata );
 	static void		onBtnSelect( void* userdata );
 	static void		onBtnCancel( void* userdata );
@@ -175,6 +179,7 @@ class LLFloaterTexturePicker : public LLFloater
 	LLFilterEditor*		mFilterEdit;
 	LLInventoryPanel*	mInventoryPanel;
 	PermissionMask		mImmediateFilterPermMask;
+	PermissionMask		mDnDFilterPermMask;
 	PermissionMask		mNonImmediateFilterPermMask;
 	BOOL				mCanApplyImmediately;
 	BOOL				mNoCopyTextureSelected;
@@ -184,12 +189,18 @@ class LLFloaterTexturePicker : public LLFloater
 	
 	LLRadioGroup*		mModeSelector;
 	LLScrollListCtrl*	mLocalScrollCtrl;
+
+private:
+	bool mCanApply;
+	bool mCanPreview;
+	texture_selected_callback mTextureSelectedCallback;
 };
 
 LLFloaterTexturePicker::LLFloaterTexturePicker(	
 	LLTextureCtrl* owner,
 	const std::string& label,
 	PermissionMask immediate_filter_perm_mask,
+	PermissionMask dnd_filter_perm_mask,
 	PermissionMask non_immediate_filter_perm_mask,
 	BOOL can_apply_immediately,
 	LLUIImagePtr fallback_image)
@@ -205,9 +216,12 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 	mActive( TRUE ),
 	mFilterEdit(NULL),
 	mImmediateFilterPermMask(immediate_filter_perm_mask),
+	mDnDFilterPermMask(dnd_filter_perm_mask),
 	mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
 	mContextConeOpacity(0.f),
-	mSelectedItemPinned( FALSE )
+	mSelectedItemPinned( FALSE ),
+	mCanApply(true),
+	mCanPreview(true)
 {
 	buildFromFile("floater_texture_ctrl.xml");
 	mCanApplyImmediately = can_apply_immediately;
@@ -319,7 +333,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
 		if (xfer) item_perm_mask |= PERM_TRANSFER;
 		
 		//PermissionMask filter_perm_mask = getFilterPermMask();  Commented out due to no-copy texture loss.
-		PermissionMask filter_perm_mask = mImmediateFilterPermMask;
+		PermissionMask filter_perm_mask = mDnDFilterPermMask;
 		if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
 		{
 			if (drop)
@@ -464,7 +478,7 @@ BOOL LLFloaterTexturePicker::postBuild()
 
 	mNoCopyTextureSelected = FALSE;
 
-	getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("ApplyTextureImmediately"));
+	getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
 	childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
 
 	if (!mCanApplyImmediately)
@@ -546,7 +560,7 @@ void LLFloaterTexturePicker::draw()
 
 	// if we're inactive, gray out "apply immediate" checkbox
 	getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
-	getChildView("Select")->setEnabled(mActive);
+	getChildView("Select")->setEnabled(mActive && mCanApply);
 	getChildView("Pipette")->setEnabled(mActive);
 	getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
 
@@ -702,8 +716,7 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask()
 
 void LLFloaterTexturePicker::commitIfImmediateSet()
 {
-	bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
-	if (!mNoCopyTextureSelected && apply_immediate && mOwner)
+	if (!mNoCopyTextureSelected && mOwner && mCanApply)
 	{
 		mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
 	}
@@ -713,6 +726,7 @@ void LLFloaterTexturePicker::commitIfImmediateSet()
 void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
 {
 	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+	self->setCanApply(true, true);
 	if (self->mOwner)
 	{
 		self->setImageID( self->mOwner->getDefaultImageAssetID() );
@@ -724,6 +738,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
 void LLFloaterTexturePicker::onBtnWhite(void* userdata)
 {
 	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+	self->setCanApply(true, true);
 	self->setImageID( self->mWhiteImageAssetID );
 	self->commitIfImmediateSet();
 }
@@ -804,13 +819,14 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 		mNoCopyTextureSelected = FALSE;
 		if (itemp)
 		{
+			mTextureSelectedCallback(itemp);
 			if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
 			{
 				mNoCopyTextureSelected = TRUE;
 			}
 			mImageAssetID = itemp->getAssetUUID();
 			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-			if (user_action)
+			if (user_action && mCanPreview)
 			{
 				// only commit intentional selections, not implicit ones
 				commitIfImmediateSet();
@@ -947,7 +963,7 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da
 	LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
 
 	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
-	gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get());
+	gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
 
 	picker->updateFilterPermMask();
 	picker->commitIfImmediateSet();
@@ -958,6 +974,16 @@ void LLFloaterTexturePicker::updateFilterPermMask()
 	//mInventoryPanel->setFilterPermMask( getFilterPermMask() );  Commented out due to no-copy texture loss.
 }
 
+void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)
+{
+	getChildRef<LLUICtrl>("Select").setEnabled(can_apply);
+	getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview);
+	getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
+
+	mCanApply = can_apply;
+	mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false;
+}
+
 void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 {
 	std::string upper_case_search_string = search_string;
@@ -1108,6 +1134,15 @@ void LLTextureCtrl::setCanApplyImmediately(BOOL b)
 	}
 }
 
+void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
+{
+	LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+	if( floaterp )
+	{
+		floaterp->setCanApply(can_preview, can_apply);
+	}
+}
+
 void LLTextureCtrl::setVisible( BOOL visible ) 
 {
 	if( !visible )
@@ -1188,12 +1223,19 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
 			this,
 			mLabel,
 			mImmediateFilterPermMask,
+			mDnDFilterPermMask,
 			mNonImmediateFilterPermMask,
 			mCanApplyImmediately,
 			mFallbackImage);
 
 		mFloaterHandle = floaterp->getHandle();
 
+		LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+		if (texture_floaterp && mOnTextureSelectedCallback)
+		{
+			texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
+		}
+
 		LLFloater* root_floater = gFloaterView->getParentFloater(this);
 		if (root_floater)
 			root_floater->addDependentFloater(floaterp);
@@ -1318,6 +1360,16 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
 	}
 }
 
+void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
+{
+	mOnTextureSelectedCallback = cb;
+	LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+	if (floaterp)
+	{
+		floaterp->setTextureSelectedCallback(cb);
+	}
+}
+
 void	LLTextureCtrl::setImageAssetName(const std::string& name)
 {
 	LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 3abe84dcc31a630ad2ea3c1903e37d9eb9d71c9c..599d9c70c521e656efabeb1ad12febb0b41094d1 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -43,6 +43,7 @@ class LLViewerFetchedTexture;
 
 // used for setting drag & drop callbacks.
 typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
+typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
 
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -147,8 +148,12 @@ class LLTextureCtrl
 	void			setCaption(const std::string& caption);
 	void			setCanApplyImmediately(BOOL b);
 
+	void			setCanApply(bool can_preview, bool can_apply);
+
 	void			setImmediateFilterPermMask(PermissionMask mask)
 					{ mImmediateFilterPermMask = mask; }
+	void			setDnDFilterPermMask(PermissionMask mask)
+						{ mDnDFilterPermMask = mask; }
 	void			setNonImmediateFilterPermMask(PermissionMask mask)
 					{ mNonImmediateFilterPermMask = mask; }
 	PermissionMask	getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
@@ -172,6 +177,11 @@ class LLTextureCtrl
 	
 	void setOnSelectCallback(commit_callback_t cb)	{ mOnSelectCallback = cb; }
 
+	/*
+	 * callback for changing texture selection in inventory list of texture floater
+	 */
+	void setOnTextureSelectedCallback(texture_selected_callback cb);
+
 	void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
 
 	LLViewerFetchedTexture* getTexture() { return mTexturep; }
@@ -185,6 +195,7 @@ class LLTextureCtrl
 	drag_n_drop_callback	 	mDropCallback;
 	commit_callback_t		 	mOnCancelCallback;
 	commit_callback_t		 	mOnSelectCallback;
+	texture_selected_callback	mOnTextureSelectedCallback;
 	LLPointer<LLViewerFetchedTexture> mTexturep;
 	LLUIColor				 	mBorderColor;
 	LLUUID					 	mImageItemID;
@@ -198,6 +209,7 @@ class LLTextureCtrl
 	std::string				 	mLabel;
 	BOOL					 	mAllowNoTexture; // If true, the user can select "none" as an option
 	PermissionMask			 	mImmediateFilterPermMask;
+	PermissionMask				mDnDFilterPermMask;
 	PermissionMask			 	mNonImmediateFilterPermMask;
 	BOOL					 	mCanApplyImmediately;
 	BOOL					 	mCommitOnSelection;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 425bf7ee871f41b5ae8ba863e1fd41c7e9ea2c08..52d085dd2cf946231e48226413909e593d6d7e37 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -510,7 +510,7 @@ void LLGLTexMemBar::draw()
 	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
 	F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
 	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
-	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
+	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
 	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
 	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
 	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index a473ee7ce03f42a80f65c9136fccffc1531302d2..d629f3abac361816a40f8fe6542fdadf4d28b61d 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -457,7 +457,7 @@ button_name_set_t getButtonDisableList(const std::string& notification_name, con
 	{
 		search_map = user_give_item_disable_map;
 	}
-	else if("TeleportOffered" == notification_name)
+	else if(("TeleportOffered" == notification_name) || ("TeleportOffered_MaturityExceeded" == notification_name))
 	{
 		search_map = teleport_offered_disable_map;
 	}
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 245c2a23e63b40d39325867d3b02351c9cc73e9c..41aee484dbc6dc3566b360d0cfacbb817946c68e 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -93,6 +93,13 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 
 	static S32 getOperationId() { return sOperationId; }
 
+	// deal with permissions of object, etc. returns TRUE if drop can
+	// proceed, otherwise FALSE.
+	static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
+						 LLInventoryItem* item,
+						 LLToolDragAndDrop::ESource source,
+						 const LLUUID& src_id);
+
 protected:
 	enum EDropTarget
 	{
@@ -219,13 +226,6 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 	// inventory items to determine if a drop would be ok.
 	static EAcceptance willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item);
 
-	// deal with permissions of object, etc. returns TRUE if drop can
-	// proceed, otherwise FALSE.
-	static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
-						 LLInventoryItem* item,
-						 LLToolDragAndDrop::ESource source,
-						 const LLUUID& src_id);
-
 public:
 	// helper functions
 	static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); }
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 718201e381ad43dbea301b0618632dbb76da10ee..0d5daf129fc51c471e59ef9242ea34111c4d62ef 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -225,7 +225,8 @@ BOOL LLVisualParamHint::render()
 
 	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
 
-	if (gAgentAvatarp->mDrawable.notNull())
+	if (gAgentAvatarp->mDrawable.notNull() &&
+		gAgentAvatarp->mDrawable->getFace(0))
 	{
 		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();
 		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index bf1f8808a7028a43658683c8a195f8ede6aae07d..cbd16e873d639eba98fd422d44cd69881ae27e31 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -251,7 +251,7 @@ void LLTracker::render3D()
 				instance()->mBeaconText->setDoFade(FALSE);
 			}
 			
-			F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->mTrackedPositionGlobal, 0.0f);
+			F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->getTrackedPositionGlobal(), 0.0f);
 			if (dist < DESTINATION_REACHED_RADIUS)
 			{
 				instance()->stopTrackingAvatar();
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 2447f5dea8da6928d025839d4ca183a53321af3f..8d8c401dac5044cc0c638c7e70597a3bed7d9376 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -41,6 +41,7 @@
 #include "llstartup.h"
 #include "llviewerparcelmgr.h"
 #include "llparcel.h"
+#include "llviewermessage.h"
 
 /////////////////////////////////////////////////////////
 
@@ -49,15 +50,22 @@ LLViewerAudio::LLViewerAudio() :
 	mFadeState(FADE_IDLE),
 	mFadeTime(),
     mIdleListnerActive(false),
-	mForcedTeleportFade(false)
+	mForcedTeleportFade(false),
+	mWasPlaying(false)
 {
 	mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->
 		setTeleportFailedCallback(boost::bind(&LLViewerAudio::onTeleportFailed, this));
+	mTeleportFinishedConnection = LLViewerParcelMgr::getInstance()->
+		setTeleportFinishedCallback(boost::bind(&LLViewerAudio::onTeleportFinished, this, _1, _2));
+	mTeleportStartedConnection = LLViewerMessage::getInstance()->
+		setTeleportStartedCallback(boost::bind(&LLViewerAudio::onTeleportStarted, this));
 }
 
 LLViewerAudio::~LLViewerAudio()
 {
 	mTeleportFailedConnection.disconnect();
+	mTeleportFinishedConnection.disconnect();
+	mTeleportStartedConnection.disconnect();
 }
 
 void LLViewerAudio::registerIdleListener()
@@ -67,7 +75,6 @@ void LLViewerAudio::registerIdleListener()
 		mIdleListnerActive = true;
 		doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this)));
 	}
-
 }
 
 void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
@@ -245,16 +252,54 @@ F32 LLViewerAudio::getFadeVolume()
 	return fade_volume;
 }
 
+void LLViewerAudio::onTeleportStarted()
+{
+	if (!LLViewerAudio::getInstance()->getForcedTeleportFade())
+	{
+		// Even though the music was turned off it was starting up (with autoplay disabled) occasionally
+		// after a failed teleport or after an intra-parcel teleport.  Also, the music sometimes was not
+		// restarting after a successful intra-parcel teleport. Setting mWasPlaying fixes these issues.
+		LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty());
+		LLViewerAudio::getInstance()->setForcedTeleportFade(true);
+		LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+		LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null);
+	}
+}
+
 void LLViewerAudio::onTeleportFailed()
 {
-	if (gAudiop)
+	// Calling audio_update_volume makes sure that the music stream is properly set to be restored to
+	// its previous value
+	audio_update_volume(false);
+
+	if (gAudiop && mWasPlaying)
+	{
+		LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+		if (parcel)
+		{
+			mNextStreamURI = parcel->getMusicURL();
+			llinfos << "Teleport failed -- setting music stream to " << mNextStreamURI << llendl;
+		}
+	}
+	mWasPlaying = false;
+}
+
+void LLViewerAudio::onTeleportFinished(const LLVector3d& pos, const bool& local)
+{
+	// Calling audio_update_volume makes sure that the music stream is properly set to be restored to
+	// its previous value
+	audio_update_volume(false);
+
+	if (gAudiop && local && mWasPlaying)
 	{
 		LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
 		if (parcel)
 		{
 			mNextStreamURI = parcel->getMusicURL();
+			llinfos << "Intraparcel teleport -- setting music stream to " << mNextStreamURI << llendl;
 		}
 	}
+	mWasPlaying = false;
 }
 
 void init_audio() 
@@ -360,15 +405,9 @@ void audio_update_volume(bool force_update)
 	// Streaming Music
 	if (gAudiop) 
 	{
-		if (progress_view_visible  && !LLViewerAudio::getInstance()->getForcedTeleportFade())
-		{
-			LLViewerAudio::getInstance()->setForcedTeleportFade(true);
-			LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
-			LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null);
-		}
-
-		if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade() == true)
+		if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade())
 		{
+			LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty());
 			LLViewerAudio::getInstance()->setForcedTeleportFade(false);
 		}
 
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index a3da9fc6b8c12844d0df7995ba0ab696f3d2f187..8c302c65492456033c91401557c2474472321be9 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -66,6 +66,7 @@ class LLViewerAudio : public LLSingleton<LLViewerAudio>
 	bool getForcedTeleportFade() { return mForcedTeleportFade; };
 	void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ;
 	void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ;
+	void setWasPlaying(bool playing) { mWasPlaying = playing;} ;
 
 private:
 
@@ -76,13 +77,17 @@ class LLViewerAudio : public LLSingleton<LLViewerAudio>
 	LLFrameTimer stream_fade_timer;
 	bool mIdleListnerActive;
 	bool mForcedTeleportFade;
+	bool mWasPlaying;
 	boost::signals2::connection	mTeleportFailedConnection;
+	boost::signals2::connection	mTeleportFinishedConnection;
+	boost::signals2::connection mTeleportStartedConnection;
 
 	void registerIdleListener();
 	void deregisterIdleListener() { mIdleListnerActive = false; };
 	void startFading();
 	void onTeleportFailed();
-
+	void onTeleportFinished(const LLVector3d& pos, const bool& local);
+	void onTeleportStarted();
 };
 
 #endif //LL_VIEWER_H
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index f2712e7590880a38175ddcf9974dcdb13c1d86db..dec1615246ccd50dc22ef0b6ef779f69915ea173 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -71,8 +71,12 @@
 #include "llpaneloutfitsinventory.h"
 #include "llpanellogin.h"
 #include "llpaneltopinfobar.h"
+#include "llspellcheck.h"
 #include "llupdaterservice.h"
 
+// Third party library includes
+#include <boost/algorithm/string.hpp>
+
 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
 BOOL 				gHackGodmode = FALSE;
 #endif
@@ -325,7 +329,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
 
 static bool handleUseOcclusionChanged(const LLSD& newvalue)
 {
-	LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery 
+	LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction
 		&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
 	return true;
 }
@@ -337,15 +341,6 @@ static bool handleUploadBakedTexOldChanged(const LLSD& newvalue)
 }
 
 
-static bool handleNumpadControlChanged(const LLSD& newvalue)
-{
-	if (gKeyboard)
-	{
-		gKeyboard->setNumpadDistinct(static_cast<LLKeyboard::e_numpad_distinct>(newvalue.asInteger()));
-	}
-	return true;
-}
-
 static bool handleWLSkyDetailChanged(const LLSD&)
 {
 	if (gSky.mVOWLSkyp.notNull())
@@ -501,6 +496,25 @@ bool handleForceShowGrid(const LLSD& newvalue)
 	return true;
 }
 
+bool handleSpellCheckChanged()
+{
+	if (gSavedSettings.getBOOL("SpellCheck"))
+	{
+		std::list<std::string> dict_list;
+		std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+		boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+		if (!dict_list.empty())
+		{
+			LLSpellChecker::setUseSpellCheck(dict_list.front());
+			dict_list.pop_front();
+			LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+			return true;
+		}
+	}
+	LLSpellChecker::setUseSpellCheck(LLStringUtil::null);
+	return true;
+}
+
 bool toggle_agent_pause(const LLSD& newvalue)
 {
 	if ( newvalue.asBoolean() )
@@ -637,7 +651,6 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
-	gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
 	gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
 	gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
 	gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
@@ -706,6 +719,8 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2));
 	gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
 	gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
+	gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
+	gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
 }
 
 #if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0adb187dd20411e21274e4fe5309498831ba678f..4571d08050f0e2a5ba582a2510c16987c0abe09a 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -383,15 +383,24 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		const std::string& message = gAgent.getTeleportMessage();
 		switch( gAgent.getTeleportState() )
 		{
+		case LLAgent::TELEPORT_PENDING:
+			gTeleportDisplayTimer.reset();
+			gViewerWindow->setShowProgress(TRUE);
+			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+			gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]);
+			gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]);
+			break;
+
 		case LLAgent::TELEPORT_START:
 			// Transition to REQUESTED.  Viewer has sent some kind
 			// of TeleportRequest to the source simulator
 			gTeleportDisplayTimer.reset();
 			gViewerWindow->setShowProgress(TRUE);
-			gViewerWindow->setProgressPercent(0);
+			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
 			gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
 			gAgent.setTeleportMessage(
 				LLAgent::sTeleportProgressMessages["requesting"]);
+			gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]);
 			break;
 
 		case LLAgent::TELEPORT_REQUESTED:
@@ -622,11 +631,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		LLSpatialGroup::sNoDelete = TRUE;
 		LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
 
-		/*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
-		{ //force occlusion on for all render types if doing deferred render (tighter shadow frustum)
-			LLPipeline::sUseOcclusion = 3;
-		}*/
-
 		S32 occlusion = LLPipeline::sUseOcclusion;
 		if (gDepthDirty)
 		{ //depth buffer is invalid, don't overwrite occlusion state
@@ -755,12 +759,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				gTextureList.updateImages(max_image_decode_time);
 			}
 
-			{
+			/*{
 				LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);
 				//remove dead textures from GL
 				LLImageGL::deleteDeadTextures();
 				stop_glerror();
-			}
+			}*/
 		}
 
 		LLGLState::checkStates();
@@ -889,6 +893,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		{
 			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
 			LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM);
+
+			if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction)
+			{
+				gGL.setColorMask(false, false);
+				
+				U32 types[] = { 
+					LLRenderPass::PASS_SIMPLE, 
+					LLRenderPass::PASS_FULLBRIGHT, 
+					LLRenderPass::PASS_SHINY 
+				};
+
+				U32 num_types = LL_ARRAY_SIZE(types);
+				gOcclusionProgram.bind();
+				for (U32 i = 0; i < num_types; i++)
+				{
+					gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
+				}
+
+				gOcclusionProgram.unbind();
+			}
+
+
 			gGL.setColorMask(true, false);
 			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
 			{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index d0e0d0d8264363a772ca97d1cbe6fc01e23ee5dd..96303151f4eb9aca72aab75550ac82fbd2b1817f 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -30,7 +30,7 @@
 #include "llfloaterreg.h"
 
 #include "llviewerfloaterreg.h"
-
+#include "llfloaterautoreplacesettings.h"
 #include "llcompilequeue.h"
 #include "llcallfloater.h"
 #include "llfasttimerview.h"
@@ -78,7 +78,6 @@
 #include "llfloaterlandholdings.h"
 #include "llfloatermap.h"
 #include "llfloatermemleak.h"
-#include "llfloatermodelwizard.h"
 #include "llfloaternamedesc.h"
 #include "llfloaternotificationsconsole.h"
 #include "llfloaterobjectweights.h"
@@ -100,6 +99,7 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfloatersnapshot.h"
 #include "llfloatersounddevices.h"
+#include "llfloaterspellchecksettings.h"
 #include "llfloatertelehub.h"
 #include "llfloatertestinspectors.h"
 #include "llfloatertestlistview.h"
@@ -254,7 +254,10 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 	LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
 	LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>);
+	LLFloaterReg::add("prefs_spellchecker_import", "floater_spellcheck_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerImport>);
 	LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
+	LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
+	LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
 	LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
 	LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
 	LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
@@ -304,7 +307,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("upload_anim_anim", "floater_animation_anim_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
 	LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload");
 	LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelPreview>, "upload");
-	LLFloaterReg::add("upload_model_wizard", "floater_model_wizard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelWizard>);
 	LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
 	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
 
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 4e14824e69a3f726c575037a80eae56c93ad486c..3a04bbed4f9d0209113b0ce3adb2a04cc40e00a3 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -127,7 +127,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
 	{
 		for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
 		{
-			object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
+			LLFace *face = object->mDrawable->getFace(face_num);
+			if (face)
+			{
+				face->setState(LLFace::HUD_RENDER);
+			}
 		}
 	}
 
@@ -146,7 +150,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
 			{
 				for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
 				{
-					childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
+					LLFace * face = childp->mDrawable->getFace(face_num);
+					if (face)
+					{
+						face->setState(LLFace::HUD_RENDER);
+					}
 				}
 			}
 		}
@@ -254,7 +262,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
 		{
 			for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
 			{
-				object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
+				LLFace * face = object->mDrawable->getFace(face_num);
+				if (face)
+				{
+					face->clearState(LLFace::HUD_RENDER);
+				}
 			}
 		}
 	}
@@ -272,7 +284,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
 			{
 				for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
 				{
-					childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
+					LLFace * face = childp->mDrawable->getFace(face_num);
+					if (face)
+					{
+						face->clearState(LLFace::HUD_RENDER);
+					}
 				}
 			}
 		}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 34e916fec004a160db599876bbfcc7f488b47b5a..97ddfb48d2df34d46480d3dbcc6ced74fbe82bf3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -86,6 +86,7 @@
 #include "llrootview.h"
 #include "llsceneview.h"
 #include "llselectmgr.h"
+#include "llspellcheckmenuhandler.h"
 #include "llstatusbar.h"
 #include "lltextureview.h"
 #include "lltoolcomp.h"
@@ -300,7 +301,6 @@ BOOL enable_buy_land(void*);
 
 void handle_test_male(void *);
 void handle_test_female(void *);
-void handle_toggle_pg(void*);
 void handle_dump_attachments(void *);
 void handle_dump_avatar_local_textures(void*);
 void handle_debug_avatar_textures(void*);
@@ -1643,23 +1643,6 @@ class LLAdvancedTestFemale : public view_listener_t
 	}
 };
 
-
-
-///////////////
-// TOGGLE PG //
-///////////////
-
-
-class LLAdvancedTogglePG : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		handle_toggle_pg(NULL);
-		return true;
-	}
-};
-
-
 class LLAdvancedForceParamsToDefault : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -2039,7 +2022,6 @@ class LLAdvancedCompressImage : public view_listener_t
 };
 
 
-
 /////////////////////////
 // SHOW DEBUG SETTINGS //
 /////////////////////////
@@ -5122,6 +5104,78 @@ class LLEditDelete : public view_listener_t
 	}
 };
 
+void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param)
+{
+	const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+	LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+	if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+	{
+		return;
+	}
+
+	U32 index = 0;
+	if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+	{
+		return;
+	}
+
+	spellcheck_handler->replaceWithSuggestion(index);
+}
+
+bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param)
+{
+	LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl);
+	const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL;
+	const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+	if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+	{
+		return false;
+	}
+
+	U32 index = 0;
+	if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+	{
+		return false;
+	}
+
+	item->setLabel(spellcheck_handler->getSuggestion(index));
+	return true;
+}
+
+void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
+{
+	const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+	LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+	if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) )
+	{
+		spellcheck_handler->addToDictionary();
+	}
+}
+
+bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
+{
+	const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+	const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+	return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary());
+}
+
+void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
+{
+	const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+	LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+	if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) )
+	{
+		spellcheck_handler->addToIgnore();
+	}
+}
+
+bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
+{
+	const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+	const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+	return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore());
+}
+
 bool enable_object_delete()
 {
 	bool new_value = 
@@ -5367,6 +5421,14 @@ void toggle_debug_menus(void*)
 // }
 //
 
+class LLCommunicateBlockList : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
+		return true;
+	}
+};
 
 class LLWorldSetHomeLocation : public view_listener_t
 {
@@ -6738,15 +6800,6 @@ void handle_test_female(void*)
 	//gGestureList.requestResetFromServer( FALSE );
 }
 
-void handle_toggle_pg(void*)
-{
-	gAgent.setTeen( !gAgent.isTeen() );
-
-	LLFloaterWorldMap::reloadIcons(NULL);
-
-	llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl;
-}
-
 void handle_dump_attachments(void*)
 {
 	if(!isAgentAvatarValid()) return;
@@ -8072,6 +8125,19 @@ void initialize_edit_menu()
 
 }
 
+void initialize_spellcheck_menu()
+{
+	LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+	LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
+
+	commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2));
+	enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2));
+	commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1));
+	enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1));
+	commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1));
+	enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1));
+}
+
 void initialize_menus()
 {
 	// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
@@ -8152,6 +8218,9 @@ void initialize_menus()
 
 	// Me > Movement
 	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
+
+	// Communicate
+	view_listener_t::addMenu(new LLCommunicateBlockList(), "Communicate.BlockList");
 	
 	// World menu
 	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
@@ -8311,7 +8380,6 @@ void initialize_menus()
 
 	view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
 	view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
-	view_listener_t::addMenu(new LLAdvancedTogglePG(), "Advanced.TogglePG");
 	
 	// Advanced > Character (toplevel)
 	view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 87cb4efbc44fd2411f550bd76b320d8af6518773..8c40762865ea1b781198f41652112b0609a060a4 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -39,6 +39,7 @@ class LLObjectSelection;
 class LLSelectNode;
 
 void initialize_edit_menu();
+void initialize_spellcheck_menu();
 void init_menus();
 void cleanup_menus();
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a9bff67f40fed8589d8440abaec20e189d90e99f..0baf119d7021e52a0600328e775742110fc88991 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -42,6 +42,7 @@
 #include "llinventorydefines.h"
 #include "lllslconstants.h"
 #include "llregionhandle.h"
+#include "llsd.h"
 #include "llsdserialize.h"
 #include "llteleportflags.h"
 #include "lltransactionflags.h"
@@ -107,6 +108,7 @@
 #include "llagentui.h"
 #include "llpanelblockedlist.h"
 #include "llpanelplaceprofile.h"
+#include "llviewerregion.h"
 
 #include <boost/algorithm/string/split.hpp> //
 #include <boost/regex.hpp>
@@ -1992,6 +1994,46 @@ bool lure_callback(const LLSD& notification, const LLSD& response)
 }
 static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
 
+bool mature_lure_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = 0;
+	if (response.isInteger()) 
+	{
+		option = response.asInteger();
+	}
+	else
+	{
+		option = LLNotificationsUtil::getSelectedOption(notification, response);
+	}
+	
+	LLUUID from_id = notification["payload"]["from_id"].asUUID();
+	LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
+	BOOL godlike = notification["payload"]["godlike"].asBoolean();
+	U8 region_access = static_cast<U8>(notification["payload"]["region_maturity"].asInteger());
+
+	switch(option)
+	{
+	case 0:
+		{
+			// accept
+			gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(region_access));
+			gAgent.setMaturityRatingChangeDuringTeleport(region_access);
+			gAgent.teleportViaLure(lure_id, godlike);
+		}
+		break;
+	case 1:
+	default:
+		// decline
+		send_simple_im(from_id,
+					   LLStringUtil::null,
+					   IM_LURE_DECLINED,
+					   lure_id);
+		break;
+	}
+	return false;
+}
+static LLNotificationFunctorRegistration mature_lure_callback_reg("TeleportOffered_MaturityExceeded", mature_lure_callback);
+
 bool goto_url_callback(const LLSD& notification, const LLSD& response)
 {
 	std::string url = notification["payload"]["url"].asString();
@@ -2770,7 +2812,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 			chat.mSourceType = CHAT_SOURCE_OBJECT;
 
-			if(SYSTEM_FROM == name)
+			// To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
+			// enough to check only from name (i.e. fromName = "Second Life"). For example
+			// source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
+			bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
+			if(chat_from_system)
 			{
 				// System's UUID is NULL (fixes EXT-4766)
 				chat.mFromID = LLUUID::null;
@@ -2795,7 +2841,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
 			// IMs from obejcts don't open IM sessions.
 			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			if(SYSTEM_FROM != name && nearby_chat)
+			if(!chat_from_system && nearby_chat)
 			{
 				chat.mOwnerID = from_id;
 				LLSD args;
@@ -2814,7 +2860,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 
 			//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
-			if (SYSTEM_FROM != name) break;
+			if (!chat_from_system) break;
 			
 			LLSD substitutions;
 			substitutions["NAME"] = name;
@@ -2879,15 +2925,54 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{
 				LLVector3 pos, look_at;
 				U64 region_handle(0);
-				U8 region_access(0);
+				U8 region_access(SIM_ACCESS_MIN);
 				std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
 				std::string region_access_str = LLStringUtil::null;
 				std::string region_access_icn = LLStringUtil::null;
+				std::string region_access_lc  = LLStringUtil::null;
+
+				bool canUserAccessDstRegion = true;
+				bool doesUserRequireMaturityIncrease = false;
 
 				if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
 				{
 					region_access_str = LLViewerRegion::accessToString(region_access);
 					region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+					region_access_lc  = region_access_str;
+					LLStringUtil::toLower(region_access_lc);
+
+					if (!gAgent.isGodlike())
+					{
+						switch (region_access)
+						{
+						case SIM_ACCESS_MIN :
+						case SIM_ACCESS_PG :
+							break;
+						case SIM_ACCESS_MATURE :
+							if (gAgent.isTeen())
+							{
+								canUserAccessDstRegion = false;
+							}
+							else if (gAgent.prefersPG())
+							{
+								doesUserRequireMaturityIncrease = true;
+							}
+							break;
+						case SIM_ACCESS_ADULT :
+							if (!gAgent.isAdult())
+							{
+								canUserAccessDstRegion = false;
+							}
+							else if (!gAgent.prefersAdult())
+							{
+								doesUserRequireMaturityIncrease = true;
+							}
+							break;
+						default :
+							llassert(0);
+							break;
+						}
+					}
 				}
 
 				LLSD args;
@@ -2896,28 +2981,130 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				args["MESSAGE"] = message;
 				args["MATURITY_STR"] = region_access_str;
 				args["MATURITY_ICON"] = region_access_icn;
+				args["REGION_CONTENT_MATURITY"] = region_access_lc;
 				LLSD payload;
 				payload["from_id"] = from_id;
 				payload["lure_id"] = session_id;
 				payload["godlike"] = FALSE;
+				payload["region_maturity"] = region_access;
+
+				if (!canUserAccessDstRegion)
+				{
+					LLNotification::Params params("TeleportOffered_MaturityBlocked");
+					params.substitutions = args;
+					params.payload = payload;
+					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+					send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
+					send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
+				}
+				else if (doesUserRequireMaturityIncrease)
+				{
+					LLNotification::Params params("TeleportOffered_MaturityExceeded");
+					params.substitutions = args;
+					params.payload = payload;
+					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+				}
+				else
+				{
+					LLNotification::Params params("TeleportOffered");
+					params.substitutions = args;
+					params.payload = payload;
+					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+				}
 
-			    LLNotification::Params params("TeleportOffered");
-			    params.substitutions = args;
-			    params.payload = payload;
-			    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
 			}
 		}
 		break;
 
 	case IM_GODLIKE_LURE_USER:
 		{
+			LLVector3 pos, look_at;
+			U64 region_handle(0);
+			U8 region_access(SIM_ACCESS_MIN);
+			std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+			std::string region_access_str = LLStringUtil::null;
+			std::string region_access_icn = LLStringUtil::null;
+			std::string region_access_lc  = LLStringUtil::null;
+
+			bool canUserAccessDstRegion = true;
+			bool doesUserRequireMaturityIncrease = false;
+
+			if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
+			{
+				region_access_str = LLViewerRegion::accessToString(region_access);
+				region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+				region_access_lc  = region_access_str;
+				LLStringUtil::toLower(region_access_lc);
+
+				if (!gAgent.isGodlike())
+				{
+					switch (region_access)
+					{
+					case SIM_ACCESS_MIN :
+					case SIM_ACCESS_PG :
+						break;
+					case SIM_ACCESS_MATURE :
+						if (gAgent.isTeen())
+						{
+							canUserAccessDstRegion = false;
+						}
+						else if (gAgent.prefersPG())
+						{
+							doesUserRequireMaturityIncrease = true;
+						}
+						break;
+					case SIM_ACCESS_ADULT :
+						if (!gAgent.isAdult())
+						{
+							canUserAccessDstRegion = false;
+						}
+						else if (!gAgent.prefersAdult())
+						{
+							doesUserRequireMaturityIncrease = true;
+						}
+						break;
+					default :
+						llassert(0);
+						break;
+					}
+				}
+			}
+
+			LLSD args;
+			// *TODO: Translate -> [FIRST] [LAST] (maybe)
+			args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+			args["MESSAGE"] = message;
+			args["MATURITY_STR"] = region_access_str;
+			args["MATURITY_ICON"] = region_access_icn;
+			args["REGION_CONTENT_MATURITY"] = region_access_lc;
 			LLSD payload;
 			payload["from_id"] = from_id;
 			payload["lure_id"] = session_id;
 			payload["godlike"] = TRUE;
-			// do not show a message box, because you're about to be
-			// teleported.
-			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
+			payload["region_maturity"] = region_access;
+
+			if (!canUserAccessDstRegion)
+			{
+				LLNotification::Params params("TeleportOffered_MaturityBlocked");
+				params.substitutions = args;
+				params.payload = payload;
+				LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+				send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
+				send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
+			}
+			else if (doesUserRequireMaturityIncrease)
+			{
+				LLNotification::Params params("TeleportOffered_MaturityExceeded");
+				params.substitutions = args;
+				params.payload = payload;
+				LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false);
+			}
+			else
+			{
+				// do not show a message box, because you're about to be
+				// teleported.
+				LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
+			}
 		}
 		break;
 
@@ -3441,6 +3628,9 @@ void process_teleport_start(LLMessageSystem *msg, void**)
 
 	LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL;
 
+	// *NOTE: The server sends two StartTeleport packets when you are teleporting to a LM
+	LLViewerMessage::getInstance()->mTeleportStartedSignal();
+
 	if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
 	{
 		gViewerWindow->setProgressCancelButtonVisible(FALSE);
@@ -3460,11 +3650,17 @@ void process_teleport_start(LLMessageSystem *msg, void**)
 		make_ui_sound("UISndTeleportOut");
 		
 		LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " <<  teleport_flags << LL_ENDL;
+
 		// Don't call LLFirstUse::useTeleport here because this could be
 		// due to being killed, which would send you home, not to a Telehub
 	}
 }
 
+boost::signals2::connection LLViewerMessage::setTeleportStartedCallback(teleport_started_callback_t cb)
+{
+	return mTeleportStartedSignal.connect(cb);
+}
+
 void process_teleport_progress(LLMessageSystem* msg, void**)
 {
 	LLUUID agent_id;
@@ -4064,6 +4260,8 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 
 	head_rot_chg = dot(last_head_rot, head_rotation);
 
+	//static S32 msg_number = 0;		// Used for diagnostic log messages
+
 	if (force_send || 
 		(cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || 
 		(head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||	
@@ -4072,19 +4270,20 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 		control_flag_change != 0 ||
 		flag_change != 0)  
 	{
-/*
+		/* Diagnotics to show why we send the AgentUpdate message.  Also un-commment the msg_number code above and below this block
+		msg_number += 1;
 		if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)
 		{
-			//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;
-			LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL;
+			//LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL;
+			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL;
 		}
 		if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) 
 		{
-			LL_INFOS("Messaging") << "cam rot " <<  cam_rot_chg.magVec() << LL_ENDL;
+			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " <<  cam_rot_chg.magVec() << LL_ENDL;
 		}
 		if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)
 		{
-			LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL;
+			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL;
 		}
 //		if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)
 //		{
@@ -4092,9 +4291,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 //		}
 		if (control_flag_change)
 		{
-			LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL;
+			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL;
 		}
-*/
+		*/
 
 		duplicate_count = 0;
 	}
@@ -4129,6 +4328,26 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 
 	if (duplicate_count < DUP_MSGS && !gDisconnected)
 	{
+		/* More diagnostics to count AgentUpdate messages
+		static S32 update_sec = 0;
+		static S32 update_count = 0;
+		static S32 max_update_count = 0;
+		S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() );
+		update_count += 1;
+		if (cur_sec != update_sec)
+		{
+			if (update_sec != 0)
+			{
+				update_sec = cur_sec;
+				//msg_number = 0;
+				max_update_count = llmax(max_update_count, update_count);
+				llinfos << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << llendl;
+			}
+			update_sec = cur_sec;
+			update_count = 0;
+		}
+		*/
+
 		LLFastTimer t(FTM_AGENT_UPDATE_SEND);
 		// Build the message
 		msg->newMessageFast(_PREHASH_AgentUpdate);
@@ -4297,8 +4516,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
 			LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
 		}
 
-		LLSelectMgr::getInstance()->removeObjectFromSelections(id);
-
 		// ...don't kill the avatar
 		if (!(id == gAgentID))
 		{
@@ -4321,6 +4538,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
 				gObjectList.mNumUnknownKills++;
 			}
 		}
+
+		// We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,
+        // which is using the object, release the mouse capture correctly when the object dies.
+        // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().
+		LLSelectMgr::getInstance()->removeObjectFromSelections(id);
+
 	}
 }
 
@@ -5389,23 +5612,35 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
 	}
 }
 
-
-
-bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
+bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	
 	if (0 == option)
 	{
 		// set the preference to the maturity of the region we're calling
-		int preferredMaturity = notification["payload"]["_region_access"].asInteger();
-		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
-		gAgent.sendMaturityPreferenceToServer(preferredMaturity);
+		U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
+		gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
+	}
+	
+	return false;
+}
 
-		// notify user that the maturity preference has been changed
-		LLSD args;
-		args["RATING"] = LLViewerRegion::accessToString(preferredMaturity);
-		LLNotificationsUtil::add("PreferredMaturityChanged", args);
+bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	
+	if (0 == option)
+	{
+		// set the preference to the maturity of the region we're calling
+		U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
+		gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
+		gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity);
+		gAgent.restartFailedTeleportRequest();
+	}
+	else
+	{
+		gAgent.clearTeleportRequest();
 	}
 	
 	return false;
@@ -5414,39 +5649,148 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD&
 // some of the server notifications need special handling. This is where we do that.
 bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
 {
-	int regionAccess = llsdBlock["_region_access"].asInteger();
-	llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
+	U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger());
+	std::string regionMaturity = LLViewerRegion::accessToString(regionAccess);
+	LLStringUtil::toLower(regionMaturity);
+	llsdBlock["REGIONMATURITY"] = regionMaturity;
 	
-	// we're going to throw the LLSD in there in case anyone ever wants to use it
-	LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock);
+	bool returnValue = false;
+	LLNotificationPtr maturityLevelNotification;
+	std::string notifySuffix = "_Notify";
+	if (regionAccess == SIM_ACCESS_MATURE)
+	{
+		if (gAgent.isTeen())
+		{
+			gAgent.clearTeleportRequest();
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+			returnValue = true;
+
+			notifySuffix = "_NotifyAdultsOnly";
+		}
+		else if (gAgent.prefersPG())
+		{
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+			returnValue = true;
+		}
+		else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0)
+		{
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock);
+			returnValue = true;
+		}
+	}
+	else if (regionAccess == SIM_ACCESS_ADULT)
+	{
+		if (!gAgent.isAdult())
+		{
+			gAgent.clearTeleportRequest();
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+			returnValue = true;
+
+			notifySuffix = "_NotifyAdultsOnly";
+		}
+		else if (gAgent.prefersPG() || gAgent.prefersMature())
+		{
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+			returnValue = true;
+		}
+		else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0)
+		{
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock);
+			returnValue = true;
+		}
+	}
+
+	if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored())
+	{
+		// Given a simple notification if no maturityLevelNotification is set or it is ignore
+		LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock);
+	}
+
+	return returnValue;
+}
+
+// some of the server notifications need special handling. This is where we do that.
+bool handle_teleport_access_blocked(LLSD& llsdBlock)
+{
+	std::string notificationID("TeleportEntryAccessBlocked");
+	U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger());
+	std::string regionMaturity = LLViewerRegion::accessToString(regionAccess);
+	LLStringUtil::toLower(regionMaturity);
+	llsdBlock["REGIONMATURITY"] = regionMaturity;
 	
+	bool returnValue = false;
+	LLNotificationPtr maturityLevelNotification;
+	std::string notifySuffix = "_Notify";
 	if (regionAccess == SIM_ACCESS_MATURE)
 	{
 		if (gAgent.isTeen())
 		{
-			LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
-			return true;
+			gAgent.clearTeleportRequest();
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+			returnValue = true;
+
+			notifySuffix = "_NotifyAdultsOnly";
 		}
 		else if (gAgent.prefersPG())
 		{
-			LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
-			return true;
+			if (gAgent.hasRestartableFailedTeleportRequest())
+			{
+				maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback);
+				returnValue = true;
+			}
+			else
+			{
+				gAgent.clearTeleportRequest();
+				maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+				returnValue = true;
+			}
+		}
+		else
+		{
+			gAgent.clearTeleportRequest();
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+			returnValue = true;
 		}
 	}
 	else if (regionAccess == SIM_ACCESS_ADULT)
 	{
 		if (!gAgent.isAdult())
 		{
-			LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
-			return true;
+			gAgent.clearTeleportRequest();
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+			returnValue = true;
+
+			notifySuffix = "_NotifyAdultsOnly";
 		}
 		else if (gAgent.prefersPG() || gAgent.prefersMature())
 		{
-			LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
-			return true;
+			if (gAgent.hasRestartableFailedTeleportRequest())
+			{
+				maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback);
+				returnValue = true;
+			}
+			else
+			{
+				gAgent.clearTeleportRequest();
+				maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+				returnValue = true;
+			}
+		}
+		else
+		{
+			gAgent.clearTeleportRequest();
+			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+			returnValue = true;
 		}
 	}
-	return false;
+
+	if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored())
+	{
+		// Given a simple notification if no maturityLevelNotification is set or it is ignore
+		LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock);
+	}
+
+	return returnValue;
 }
 
 bool attempt_standard_notification(LLMessageSystem* msgsystem)
@@ -5490,16 +5834,20 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
 			 
 				RegionEntryAccessBlocked
 				RegionEntryAccessBlocked_Notify
+				RegionEntryAccessBlocked_NotifyAdultsOnly
 				RegionEntryAccessBlocked_Change
-				RegionEntryAccessBlocked_KB
+				RegionEntryAccessBlocked_AdultsOnlyContent
+				RegionEntryAccessBlocked_ChangeAndReTeleport
 				LandClaimAccessBlocked 
 				LandClaimAccessBlocked_Notify 
+				LandClaimAccessBlocked_NotifyAdultsOnly
 				LandClaimAccessBlocked_Change 
-				LandClaimAccessBlocked_KB 
+				LandClaimAccessBlocked_AdultsOnlyContent 
 				LandBuyAccessBlocked
 				LandBuyAccessBlocked_Notify
+				LandBuyAccessBlocked_NotifyAdultsOnly
 				LandBuyAccessBlocked_Change
-				LandBuyAccessBlocked_KB
+				LandBuyAccessBlocked_AdultsOnlyContent
 			 
 			-----------------------------------------------------------------------*/ 
 			if (handle_special_notification(notificationID, llsdBlock))
@@ -5551,6 +5899,30 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
 	}
 }
 
+bool handle_not_age_verified_alert(const std::string &pAlertName)
+{
+	LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName);
+	if ((notification == NULL) || notification->isIgnored())
+	{
+		LLNotificationsUtil::add(pAlertName + "_Notify");
+	}
+
+	return true;
+}
+
+bool handle_special_alerts(const std::string &pAlertName)
+{
+	bool isHandled = false;
+
+	if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0)
+	{
+		
+		isHandled = handle_not_age_verified_alert(pAlertName);
+	}
+
+	return isHandled;
+}
+
 void process_alert_core(const std::string& message, BOOL modal)
 {
 	// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
@@ -5574,7 +5946,10 @@ void process_alert_core(const std::string& message, BOOL modal)
 		// Allow the server to spawn a named alert so that server alerts can be
 		// translated out of English.
 		std::string alert_name(message.substr(ALERT_PREFIX.length()));
-		LLNotificationsUtil::add(alert_name);
+		if (!handle_special_alerts(alert_name))
+		{
+			LLNotificationsUtil::add(alert_name);
+		}
 	}
 	else if (message.find(NOTIFY_PREFIX) == 0)
 	{
@@ -6160,6 +6535,9 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 	std::string big_reason;
 	LLSD args;
 
+	// Let the interested parties know that teleport failed.
+	LLViewerParcelMgr::getInstance()->onTeleportFailed();
+
 	// if we have additional alert data
 	if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
 	{
@@ -6189,7 +6567,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 			else
 			{
 				// change notification name in this special case
-				if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
+				if (handle_teleport_access_blocked(llsd_block))
 				{
 					if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 					{
@@ -6218,9 +6596,6 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 
 	LLNotificationsUtil::add("CouldNotTeleportReason", args);
 
-	// Let the interested parties know that teleport failed.
-	LLViewerParcelMgr::getInstance()->onTeleportFailed();
-
 	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 	{
 		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 46bfb2dad06f614dd4c609e298392794e928404c..594c22ed9ca842a5d672e3c7a5c89f752d1c4f4b 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -37,6 +37,9 @@
 #include "llnotifications.h"
 #include "llextendedstatus.h"
 
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
 //
 // Forward declarations
 //
@@ -205,6 +208,15 @@ bool highlight_offered_object(const LLUUID& obj_id);
 void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid);
 void set_dad_inbox_object(const LLUUID& object_id);
 
+class LLViewerMessage : public  LLSingleton<LLViewerMessage>
+{
+public:
+	typedef boost::function<void()> teleport_started_callback_t;
+	typedef boost::signals2::signal<void()> teleport_started_signal_t;
+	boost::signals2::connection setTeleportStartedCallback(teleport_started_callback_t cb);
+
+	teleport_started_signal_t	mTeleportStartedSignal;
+};
 
 class LLOfferInfo : public LLNotificationResponderInterface
 {
@@ -253,5 +265,3 @@ class LLOfferInfo : public LLNotificationResponderInterface
 void process_feature_disabled_message(LLMessageSystem* msg, void**);
 
 #endif
-
-
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index cd300accb7f74070ea0f940d7d7d459912393d25..72fd3c1a4a2f06042976e286d2566b8a916c623a 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -432,7 +432,9 @@ void LLViewerObject::dump() const
 	llinfos << "PositionAgent: " << getPositionAgent() << llendl;
 	llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
 	llinfos << "Velocity: " << getVelocity() << llendl;
-	if (mDrawable.notNull() && mDrawable->getNumFaces())
+	if (mDrawable.notNull() && 
+		mDrawable->getNumFaces() && 
+		mDrawable->getFace(0))
 	{
 		LLFacePool *poolp = mDrawable->getFace(0)->getPool();
 		if (poolp)
@@ -2389,10 +2391,11 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
 		{	// This will put the object underground, but we can't tell if it will stop 
 			// at ground level or not
 			min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
+			// Cap maximum height
+			new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
 		}
 
 		new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
-		new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
 
 		// Check to see if it's going off the region
 		LLVector3 temp(new_pos);
@@ -2798,6 +2801,23 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
 	   (object = gObjectList.findObject(ft->mTaskID)))
 	{
 		object->loadTaskInvFile(ft->mFilename);
+
+		LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+		LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+		std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+
+		for (; it != end && pending_lst.size(); ++it)
+		{
+			LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+			if(item && item->getType() != LLAssetType::AT_CATEGORY)
+			{
+				std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+				if (id_it != pending_lst.end())
+				{
+					pending_lst.erase(id_it);
+				}
+			}
+		}
 	}
 	else
 	{
@@ -2910,7 +2930,22 @@ void LLViewerObject::updateInventory(
 	bool is_new)
 {
 	LLMemType mt(LLMemType::MTYPE_OBJECT);
-	
+
+	std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
+	std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
+
+	bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end;
+	bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL;
+
+	if (is_fetched || is_fetching)
+	{
+		return;
+	}
+	else
+	{
+		mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
+	}
+
 	// This slices the object into what we're concerned about on the
 	// viewer. The simulator will take the permissions and transfer
 	// ownership.
@@ -4477,7 +4512,11 @@ U32 LLViewerObject::getNumVertices() const
 		num_faces = mDrawable->getNumFaces();
 		for (i = 0; i < num_faces; i++)
 		{
-			num_vertices += mDrawable->getFace(i)->getGeomCount();
+			LLFace * facep = mDrawable->getFace(i);
+			if (facep)
+			{
+				num_vertices += facep->getGeomCount();
+			}
 		}
 	}
 	return num_vertices;
@@ -4492,7 +4531,11 @@ U32 LLViewerObject::getNumIndices() const
 		num_faces = mDrawable->getNumFaces();
 		for (i = 0; i < num_faces; i++)
 		{
-			num_indices += mDrawable->getFace(i)->getIndicesCount();
+			LLFace * facep = mDrawable->getFace(i);
+			if (facep)
+			{
+				num_indices += facep->getIndicesCount();
+			}
 		}
 	}
 	return num_indices;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index c8152e1539db7e447b8c5664e7d2f349802f733d..dc102b666fa4d6a9f7fad5606b7ccae96522f77b 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -684,6 +684,10 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	F32				mAppAngle;	// Apparent visual arc in degrees
 	F32				mPixelArea; // Apparent area in pixels
 
+	// IDs of of all items in the object's content which are added to the object's content,
+	// but not updated on the server yet. After item was updated, its ID will be removed from this list.
+	std::list<LLUUID> mPendingInventoryItemsIDs;
+
 	// This is the object's inventory from the viewer's perspective.
 	LLInventoryObject::object_list_t* mInventory;
 	class LLInventoryCallbackInfo
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 54ccfb9aae4d44069429441866238425b30e0094..beb68c1cbbc0eba763d7e6c9014d30df4004f17a 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1721,7 +1721,10 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
 			LLViewerObject* last_objectp = NULL;
 			for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
 			{
-				LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();
+				LLFace * facep = drawablep->getFace(face_num);
+				if (!facep) continue;
+
+				LLViewerObject* objectp = facep->getViewerObject();
 
 				if (objectp && objectp != last_objectp)
 				{
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 9db784101d9c3dd8e0aabd8fb927d8f435a0418d..ae9c31bfe77bae83a644aeb2ed0eb67537a91860 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -82,7 +82,6 @@ LLPointer<LLViewerTexture> sBlockedImage;
 LLPointer<LLViewerTexture> sPassImage;
 
 // Local functions
-void optionally_start_music(const std::string& music_url);
 void callback_start_music(S32 option, void* data);
 void optionally_prepare_video(const LLParcel *parcelp);
 void callback_prepare_video(S32 option, void* data);
@@ -1589,7 +1588,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 			if (instance->mTeleportInProgress)
 			{
 				instance->mTeleportInProgress = FALSE;
-				instance->mTeleportFinishedSignal(gAgent.getPositionGlobal());
+				instance->mTeleportFinishedSignal(gAgent.getPositionGlobal(), false);
 			}
 		}
 	}
@@ -1773,13 +1772,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 	};
 }
 
-void optionally_start_music(const std::string& music_url)
+void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
 {
 	if (gSavedSettings.getBOOL("AudioStreamingMusic"))
 	{
 		// only play music when you enter a new parcel if the UI control for this
 		// was not *explicitly* stopped by the user. (part of SL-4878)
-		LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();;
+		LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
 		if ((nearby_media_panel &&
 		     nearby_media_panel->getParcelAudioAutoStart()) ||
 		    // or they have expressed no opinion in the UI, but have autoplay on...
@@ -2559,7 +2558,7 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos
 	{
 		// Local teleport. We already have the agent parcel data.
 		// Emit the signal immediately.
-		getInstance()->mTeleportFinishedSignal(new_pos);
+		getInstance()->mTeleportFinishedSignal(new_pos, local);
 	}
 	else
 	{
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index cac8d8391cfac364cd59a707112c952a3d6eda7a..2a115494266b419a0d19a6f9d8adc065c0e560cd 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -78,8 +78,8 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 {
 
 public:
-	typedef boost::function<void (const LLVector3d&)> teleport_finished_callback_t;
-	typedef boost::signals2::signal<void (const LLVector3d&)> teleport_finished_signal_t;
+	typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t;
+	typedef boost::signals2::signal<void (const LLVector3d&, const bool&)> teleport_finished_signal_t;
 	typedef boost::function<void()> parcel_changed_callback_t;
 	typedef boost::signals2::signal<void()> parcel_changed_signal_t;
 
@@ -275,6 +275,8 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 	// *NOTE: Taken out 2005-03-21. Phoenix.
 	//void makeLandmarkAtSelection();
 
+	static void optionally_start_music(const std::string& music_url);
+
 	static void processParcelOverlay(LLMessageSystem *msg, void **user_data);
 	static void processParcelProperties(LLMessageSystem *msg, void **user_data);
 	static void processParcelAccessListReply(LLMessageSystem *msg, void **user);
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6b3e04348a1c386fb8bd174d50945ae87165394e..345023dbfa42bf0138772bddb458a42a459a9c3f 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -476,7 +476,7 @@ void LLViewerPartSim::checkParticleCount(U32 size)
 LLViewerPartSim::LLViewerPartSim()
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
-	sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount");
+	sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT);
 	static U32 id_seed = 0;
 	mID = ++id_seed;
 }
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 3e20f999c022a8695f0308c0d0ab642ab0b4291c..c9959c63ec23376039ff6b059eb2664577c09a6c 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -39,6 +39,8 @@ class LLViewerRegion;
 class LLViewerTexture;
 class LLVOPartGroup;
 
+#define LL_MAX_PARTICLE_COUNT 8192
+
 typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
 
 ///////////////////
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e3cb985ddb3a35bab24412d0d2a6f5d20f9613b0..f3771e93d974ba4efd4fbded988e49497f9da092 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -654,6 +654,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access)
 	}
 }
 
+// static
+U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access)
+{
+	U8 accessValue;
+
+	if (LLStringUtil::compareStrings(sim_access, "PG") == 0)
+	{
+		accessValue = SIM_ACCESS_PG;
+	}
+	else if (LLStringUtil::compareStrings(sim_access, "M") == 0)
+	{
+		accessValue = SIM_ACCESS_MATURE;
+	}
+	else if (LLStringUtil::compareStrings(sim_access, "A") == 0)
+	{
+		accessValue = SIM_ACCESS_ADULT;
+	}
+	else
+	{
+		accessValue = SIM_ACCESS_MIN;
+	}
+
+	return accessValue;
+}
+
 // static
 void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
 {
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c483c6ef5294a5fc99ee29315bc12d1c069039ea..7280c7f2e6b9b44102cfb47350f1e999e0039a95 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -202,6 +202,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	// Returns "M", "PG", "A" etc.
 	static std::string accessToShortString(U8 sim_access);
+	static U8          shortStringToAccess(const std::string &sim_access);
 
 	// Return access icon name
 	static std::string getAccessIcon(U8 sim_access);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 10c61c01d5c17e671dd318c7a5fb7b7fc1dcca56..a6c564a6a10e7d97c6f406058d57cbd6da522656 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -63,8 +63,16 @@ bool				LLViewerShaderMgr::sSkipReload = false;
 
 LLVector4			gShinyOrigin;
 
+//transform shaders
+LLGLSLShader			gTransformPositionProgram;
+LLGLSLShader			gTransformTexCoordProgram;
+LLGLSLShader			gTransformNormalProgram;
+LLGLSLShader			gTransformColorProgram;
+LLGLSLShader			gTransformBinormalProgram;
+
 //utility shaders
 LLGLSLShader	gOcclusionProgram;
+LLGLSLShader	gOcclusionCubeProgram;
 LLGLSLShader	gCustomAlphaProgram;
 LLGLSLShader	gGlowCombineProgram;
 LLGLSLShader	gSplatTextureRectProgram;
@@ -72,6 +80,7 @@ LLGLSLShader	gGlowCombineFXAAProgram;
 LLGLSLShader	gTwoTextureAddProgram;
 LLGLSLShader	gOneTextureNoColorProgram;
 LLGLSLShader	gDebugProgram;
+LLGLSLShader	gClipProgram;
 LLGLSLShader	gAlphaMaskProgram;
 
 //object shaders
@@ -178,6 +187,7 @@ LLGLSLShader			gDeferredSunProgram;
 LLGLSLShader			gDeferredBlurLightProgram;
 LLGLSLShader			gDeferredSoftenProgram;
 LLGLSLShader			gDeferredShadowProgram;
+LLGLSLShader			gDeferredShadowCubeProgram;
 LLGLSLShader			gDeferredShadowAlphaMaskProgram;
 LLGLSLShader			gDeferredAvatarShadowProgram;
 LLGLSLShader			gDeferredAttachmentShadowProgram;
@@ -437,7 +447,8 @@ void LLViewerShaderMgr::setShaders()
 		S32 wl_class = 2;
 		S32 water_class = 2;
 		S32 deferred_class = 0;
-		
+		S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
+
 		if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
 		    gSavedSettings.getBOOL("RenderDeferred") &&
 			gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -475,6 +486,7 @@ void LLViewerShaderMgr::setShaders()
 			gSky.mVOSkyp->forceSkyUpdate();
 		}
 
+		
 		// Load lighting shaders
 		mVertexShaderLevel[SHADER_LIGHTING] = light_class;
 		mVertexShaderLevel[SHADER_INTERFACE] = light_class;
@@ -484,6 +496,7 @@ void LLViewerShaderMgr::setShaders()
 		mVertexShaderLevel[SHADER_EFFECT] = effect_class;
 		mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;
 		mVertexShaderLevel[SHADER_DEFERRED] = deferred_class;
+		mVertexShaderLevel[SHADER_TRANSFORM] = transform_class;
 
 		BOOL loaded = loadBasicShaders();
 
@@ -493,65 +506,109 @@ void LLViewerShaderMgr::setShaders()
 			gPipeline.mVertexShadersLoaded = 1;
 
 			// Load all shaders to set max levels
-			loadShadersEnvironment();
-			loadShadersWater();
-			loadShadersWindLight();
-			loadShadersEffects();
-			loadShadersInterface();
+			loaded = loadShadersEnvironment();
+
+			if (loaded)
+			{
+				loaded = loadShadersWater();
+			}
+
+			if (loaded)
+			{
+				loaded = loadShadersWindLight();
+			}
+
+			if (loaded)
+			{
+				loaded = loadShadersEffects();
+			}
+
+			if (loaded)
+			{
+				loaded = loadShadersInterface();
+			}
 			
-			// Load max avatar shaders to set the max level
-			mVertexShaderLevel[SHADER_AVATAR] = 3;
-			mMaxAvatarShaderLevel = 3;
-						
-			if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
-			{ //hardware skinning is enabled and rigged attachment shaders loaded correctly
-				BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
-				S32 avatar_class = 1;
-				
-				// cloth is a class3 shader
-				if(avatar_cloth)
-				{
-					avatar_class = 3;
-				}
+			if (loaded)
+			{
+				loaded = loadTransformShaders();
+			}
 
-				// Set the actual level
-				mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
-				loadShadersAvatar();
-				if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
-				{
-					if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+			if (loaded)
+			{
+				// Load max avatar shaders to set the max level
+				mVertexShaderLevel[SHADER_AVATAR] = 3;
+				mMaxAvatarShaderLevel = 3;
+				
+				if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
+				{ //hardware skinning is enabled and rigged attachment shaders loaded correctly
+					BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+					S32 avatar_class = 1;
+				
+					// cloth is a class3 shader
+					if(avatar_cloth)
 					{
-						gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+						avatar_class = 3;
 					}
-					if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
+
+					// Set the actual level
+					mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
+					loadShadersAvatar();
+					if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
 					{
-						avatar_cloth = true;
+						if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+						{
+							gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+						}
+						if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
+						{
+							avatar_cloth = true;
+						}
+						else
+						{
+							avatar_cloth = false;
+						}
+						gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
 					}
-					else
+				}
+				else
+				{ //hardware skinning not possible, neither is deferred rendering
+					mVertexShaderLevel[SHADER_AVATAR] = 0;
+					mVertexShaderLevel[SHADER_DEFERRED] = 0;
+
+					if (gSavedSettings.getBOOL("RenderAvatarVP"))
 					{
-						avatar_cloth = false;
+						gSavedSettings.setBOOL("RenderDeferred", FALSE);
+						gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
+						gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
 					}
-					gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
+
+					loadShadersAvatar(); // unloads
+
+					loaded = loadShadersObject();
 				}
 			}
-			else
-			{ //hardware skinning not possible, neither is deferred rendering
-				mVertexShaderLevel[SHADER_AVATAR] = 0;
-				mVertexShaderLevel[SHADER_DEFERRED] = 0;
-
-				if (gSavedSettings.getBOOL("RenderAvatarVP"))
-				{
-					gSavedSettings.setBOOL("RenderDeferred", FALSE);
-					gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
-					gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+
+			if (!loaded)
+			{ //some shader absolutely could not load, try to fall back to a simpler setting
+				if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
+				{ //disable windlight and try again
+					gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
+					reentrance = false;
+					setShaders();
+					return;
 				}
 
-				loadShadersAvatar(); // unloads
-				loadShadersObject();
-			}
+				if (gSavedSettings.getBOOL("VertexShaderEnable"))
+				{ //disable shaders outright and try again
+					gSavedSettings.setBOOL("VertexShaderEnable", FALSE);
+					reentrance = false;
+					setShaders();
+					return;
+				}
+			}		
 
-			if (!loadShadersDeferred())
-			{
+			if (loaded && !loadShadersDeferred())
+			{ //everything else succeeded but deferred failed, disable deferred and try again
 				gSavedSettings.setBOOL("RenderDeferred", FALSE);
 				reentrance = false;
 				setShaders();
@@ -600,7 +657,9 @@ void LLViewerShaderMgr::setShaders()
 void LLViewerShaderMgr::unloadShaders()
 {
 	gOcclusionProgram.unload();
+	gOcclusionCubeProgram.unload();
 	gDebugProgram.unload();
+	gClipProgram.unload();
 	gAlphaMaskProgram.unload();
 	gUIProgram.unload();
 	gCustomAlphaProgram.unload();
@@ -692,6 +751,12 @@ void LLViewerShaderMgr::unloadShaders()
 	gDeferredSkinnedBumpProgram.unload();
 	gDeferredSkinnedAlphaProgram.unload();
 
+	gTransformPositionProgram.unload();
+	gTransformTexCoordProgram.unload();
+	gTransformNormalProgram.unload();
+	gTransformColorProgram.unload();
+	gTransformBinormalProgram.unload();
+
 	mVertexShaderLevel[SHADER_LIGHTING] = 0;
 	mVertexShaderLevel[SHADER_OBJECT] = 0;
 	mVertexShaderLevel[SHADER_AVATAR] = 0;
@@ -700,6 +765,7 @@ void LLViewerShaderMgr::unloadShaders()
 	mVertexShaderLevel[SHADER_INTERFACE] = 0;
 	mVertexShaderLevel[SHADER_EFFECT] = 0;
 	mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+	mVertexShaderLevel[SHADER_TRANSFORM] = 0;
 
 	gPipeline.mVertexShadersLoaded = 0;
 }
@@ -828,7 +894,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
 	if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
 	{
 		gTerrainProgram.unload();
-		return FALSE;
+		return TRUE;
 	}
 
 	if (success)
@@ -868,7 +934,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
 		gWaterProgram.unload();
 		gUnderWaterProgram.unload();
 		gTerrainWaterProgram.unload();
-		return FALSE;
+		return TRUE;
 	}
 
 	if (success)
@@ -953,7 +1019,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
 		gGlowExtractProgram.unload();
 		gPostColorFilterProgram.unload();	
 		gPostNightVisionProgram.unload();
-		return FALSE;
+		return TRUE;
 	}
 
 	if (success)
@@ -1013,6 +1079,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredBlurLightProgram.unload();
 		gDeferredSoftenProgram.unload();
 		gDeferredShadowProgram.unload();
+		gDeferredShadowCubeProgram.unload();
 		gDeferredShadowAlphaMaskProgram.unload();
 		gDeferredAvatarShadowProgram.unload();
 		gDeferredAttachmentShadowProgram.unload();
@@ -1200,7 +1267,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
 		gDeferredSpotLightProgram.mShaderFiles.clear();
 		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
-		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredSpotLightProgram.createShader(NULL, NULL);
 	}
@@ -1209,7 +1276,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 	{
 		gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
 		gDeferredMultiSpotLightProgram.mShaderFiles.clear();
-		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
 		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
 		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
 		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
@@ -1366,6 +1433,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
 		success = gDeferredShadowProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
+		gDeferredShadowCubeProgram.mShaderFiles.clear();
+		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));
+		gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+		success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
@@ -2410,7 +2487,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
 		gAvatarWaterProgram.unload();
 		gAvatarEyeballProgram.unload();
 		gAvatarPickProgram.unload();
-		return FALSE;
+		return TRUE;
 	}
 
 	if (success)
@@ -2504,7 +2581,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 	if (mVertexShaderLevel[SHADER_INTERFACE] == 0)
 	{
 		gHighlightProgram.unload();
-		return FALSE;
+		return TRUE;
 	}
 	
 	if (success)
@@ -2645,6 +2722,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		success = gOcclusionProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
+		gOcclusionCubeProgram.mShaderFiles.clear();
+		gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));
+		gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gOcclusionCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gOcclusionCubeProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gDebugProgram.mName = "Debug Shader";
@@ -2655,6 +2742,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		success = gDebugProgram.createShader(NULL, NULL);
 	}
 
+	if (success)
+	{
+		gClipProgram.mName = "Clip Shader";
+		gClipProgram.mShaderFiles.clear();
+		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));
+		gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB));
+		gClipProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+		success = gClipProgram.createShader(NULL, NULL);
+	}
+
 	if (success)
 	{
 		gAlphaMaskProgram.mName = "Alpha Mask Shader";
@@ -2682,7 +2779,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
 	{
 		gWLSkyProgram.unload();
 		gWLCloudProgram.unload();
-		return FALSE;
+		return TRUE;
 	}
 
 	if (success)
@@ -2712,6 +2809,95 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
 	return success;
 }
 
+BOOL LLViewerShaderMgr::loadTransformShaders()
+{
+	BOOL success = TRUE;
+	
+	if (mVertexShaderLevel[SHADER_TRANSFORM] < 1)
+	{
+		gTransformPositionProgram.unload();
+		gTransformTexCoordProgram.unload();
+		gTransformNormalProgram.unload();
+		gTransformColorProgram.unload();
+		gTransformBinormalProgram.unload();
+		return TRUE;
+	}
+
+	if (success)
+	{
+		gTransformPositionProgram.mName = "Position Transform Shader";
+		gTransformPositionProgram.mShaderFiles.clear();
+		gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
+		gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+		const char* varyings[] = {
+			"position_out",
+			"texture_index_out",
+		};
+	
+		success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings);
+	}
+
+	if (success)
+	{
+		gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
+		gTransformTexCoordProgram.mShaderFiles.clear();
+		gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
+		gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+		const char* varyings[] = {
+			"texcoord_out",
+		};
+	
+		success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings);
+	}
+
+	if (success)
+	{
+		gTransformNormalProgram.mName = "Normal Transform Shader";
+		gTransformNormalProgram.mShaderFiles.clear();
+		gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
+		gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+		const char* varyings[] = {
+			"normal_out",
+		};
+	
+		success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings);
+	}
+
+	if (success)
+	{
+		gTransformColorProgram.mName = "Color Transform Shader";
+		gTransformColorProgram.mShaderFiles.clear();
+		gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
+		gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+		const char* varyings[] = {
+			"color_out",
+		};
+	
+		success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings);
+	}
+
+	if (success)
+	{
+		gTransformBinormalProgram.mName = "Binormal Transform Shader";
+		gTransformBinormalProgram.mShaderFiles.clear();
+		gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
+		gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+		const char* varyings[] = {
+			"binormal_out",
+		};
+	
+		success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings);
+	}
+
+	
+	return success;
+}
+
 std::string LLViewerShaderMgr::getShaderDirPrefix(void)
 {
 	return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 95eb551bf1ba6837f1c8e98762ae3863f41a99ec..8f7ff8dd2f7cdac011344848f4100c0ff9e25bc4 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -54,6 +54,7 @@ class LLViewerShaderMgr: public LLShaderMgr
 	BOOL loadShadersWater();
 	BOOL loadShadersInterface();
 	BOOL loadShadersWindLight();
+	BOOL loadTransformShaders();
 
 	std::vector<S32> mVertexShaderLevel;
 	S32	mMaxAvatarShaderLevel;
@@ -69,6 +70,7 @@ class LLViewerShaderMgr: public LLShaderMgr
 		SHADER_WINDLIGHT,
 		SHADER_WATER,
 		SHADER_DEFERRED,
+		SHADER_TRANSFORM,
 		SHADER_COUNT
 	};
 
@@ -209,13 +211,24 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade
 
 extern LLVector4			gShinyOrigin;
 
+//transform shaders
+extern LLGLSLShader			gTransformPositionProgram;
+extern LLGLSLShader			gTransformTexCoordProgram;
+extern LLGLSLShader			gTransformNormalProgram;
+extern LLGLSLShader			gTransformColorProgram;
+extern LLGLSLShader			gTransformBinormalProgram;
+
+
+
 //utility shaders
 extern LLGLSLShader			gOcclusionProgram;
+extern LLGLSLShader			gOcclusionCubeProgram;
 extern LLGLSLShader			gCustomAlphaProgram;
 extern LLGLSLShader			gGlowCombineProgram;
 extern LLGLSLShader			gSplatTextureRectProgram;
 extern LLGLSLShader			gGlowCombineFXAAProgram;
 extern LLGLSLShader			gDebugProgram;
+extern LLGLSLShader			gClipProgram;
 extern LLGLSLShader			gAlphaMaskProgram;
 
 //output tex0[tc0] + tex1[tc1]
@@ -328,6 +341,7 @@ extern LLGLSLShader			gDeferredBlurLightProgram;
 extern LLGLSLShader			gDeferredAvatarProgram;
 extern LLGLSLShader			gDeferredSoftenProgram;
 extern LLGLSLShader			gDeferredShadowProgram;
+extern LLGLSLShader			gDeferredShadowCubeProgram;
 extern LLGLSLShader			gDeferredShadowAlphaMaskProgram;
 extern LLGLSLShader			gDeferredPostProgram;
 extern LLGLSLShader			gDeferredCoFProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 497e95c5e3712286b376b608cc666fac4a6df5b4..28f4ec72f30a9097420dfaa20cf3f5c93c9587b3 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -789,6 +789,24 @@ void send_stats()
 	system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
 	system["gpu_vendor"] = gGLManager.mGLVendorShort;
 	system["gpu_version"] = gGLManager.mDriverVersionVendorString;
+	system["opengl_version"] = gGLManager.mGLVersionString;
+
+	S32 shader_level = 0;
+	if (LLPipeline::sRenderDeferred)
+	{
+		shader_level = 3;
+	}
+	else if (gPipeline.canUseWindLightShadersOnObjects())
+	{
+		shader_level = 2;
+	}
+	else if (gPipeline.canUseVertexShaders())
+	{
+		shader_level = 1;
+	}
+
+
+	system["shader_level"] = shader_level;
 
 	LLSD &download = body["downloads"];
 
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d844aeb12a407958b42abdff73780dcfd4d4c5be..7f638a24bf58aa1e93d790311c106c5c1ed09a20 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1398,10 +1398,10 @@ void LLViewerFetchedTexture::dump()
 // ONLY called from LLViewerFetchedTextureList
 void LLViewerFetchedTexture::destroyTexture() 
 {
-	if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
-	{
-		return ;
-	}
+	//if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
+	//{
+	//	return ;
+	//}
 	if (mNeedsCreateTexture)//return if in the process of generating a new texture.
 	{
 		return ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 528e0080b78a61987fff9243925959432d885566..9a6c0569a996056846df55a8769e6263f7edfcd4 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -705,7 +705,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
 			// Flush formatted images using a lazy flush
 			//
 			const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding
-			const F32 MAX_INACTIVE_TIME  = 50.f; // actually delete
+			const F32 MAX_INACTIVE_TIME  = 20.f; // actually delete
 			S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
 			
 			S32 num_refs = imagep->getNumRefs();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 39e330ad666c727d874576d4457e88666b0b0b9a..7afb13547085fc9292929db3ee60d17128f7b75e 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -175,6 +175,7 @@
 #include "llviewershadermgr.h"
 #include "llviewerstats.h"
 #include "llvoavatarself.h"
+#include "llvopartgroup.h"
 #include "llvovolume.h"
 #include "llworld.h"
 #include "llworldmapview.h"
@@ -613,7 +614,7 @@ class LLDebugText
 				addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
 					LLMeshRepository::sHTTPRetryCount));
 				ypos += y_inc;
-
+				
 				addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
 				ypos += y_inc;
 
@@ -1704,9 +1705,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	// Can't have spaces in settings.ini strings, so use underscores instead and convert them.
 	LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
 
-	// sync the keyboard's setting with the saved setting
-	gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
-
 	mDebugText = new LLDebugText(this);
 
 	mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
@@ -1973,12 +1971,12 @@ void LLViewerWindow::shutdownViews()
 		gMorphView->setVisible(FALSE);
 	}
 	llinfos << "Global views cleaned." << llendl ;
-	
+
 	// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
 	// will crump with LL_ERRS.
 	LLModalDialog::shutdownModals();
 	llinfos << "LLModalDialog shut down." << llendl; 
-
+	
 	// destroy the nav bar, not currently part of gViewerWindow
 	// *TODO: Make LLNavigationBar part of gViewerWindow
 	if (LLNavigationBar::instanceExists())
@@ -1986,17 +1984,17 @@ void LLViewerWindow::shutdownViews()
 		delete LLNavigationBar::getInstance();
 	}
 	llinfos << "LLNavigationBar destroyed." << llendl ;
-	
+
 	// destroy menus after instantiating navbar above, as it needs
 	// access to gMenuHolder
 	cleanup_menus();
 	llinfos << "menus destroyed." << llendl ;
-	
+
 	// Delete all child views.
 	delete mRootView;
 	mRootView = NULL;
 	llinfos << "RootView deleted." << llendl ;
-	
+
 	// Automatically deleted as children of mRootView.  Fix the globals.
 	gStatusBar = NULL;
 	gIMMgr = NULL;
@@ -4660,6 +4658,8 @@ void LLViewerWindow::stopGL(BOOL save_state)
 		LLVOAvatar::destroyGL();
 		stop_glerror();
 
+		LLVOPartGroup::destroyGL();
+
 		LLViewerDynamicTexture::destroyGL();
 		stop_glerror();
 
@@ -4713,7 +4713,8 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
 		gBumpImageList.restoreGL();
 		LLViewerDynamicTexture::restoreGL();
 		LLVOAvatar::restoreGL();
-		
+		LLVOPartGroup::restoreGL();
+
 		gResizeScreenTexture = TRUE;
 		gWindowResized = TRUE;
 
@@ -5196,8 +5197,10 @@ void LLPickInfo::getSurfaceInfo()
 			if (objectp->mDrawable.notNull() && mObjectFace > -1)
 			{
 				LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
-
-				mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+				if (facep)
+				{
+					mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+				}
 			}
 
 			// and XY coords:
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index eada77156e477aa9c4cc1640995537c8acaeeaa4..33dc12c473a64062c2180dde1d8696119daf3155 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -961,7 +961,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
 		}
 		if (mBakedTextureDatas[i].mMaskTexName)
 		{
-			glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+			LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
 			mBakedTextureDatas[i].mMaskTexName = 0 ;
 		}
 	}
@@ -2094,11 +2094,17 @@ void LLVOAvatar::releaseMeshData()
 	if (mDrawable.notNull())
 	{
 		LLFace* facep = mDrawable->getFace(0);
-		facep->setSize(0, 0);
-		for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+		if (facep)
 		{
-			facep = mDrawable->getFace(i);
 			facep->setSize(0, 0);
+			for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+			{
+				facep = mDrawable->getFace(i);
+				if (facep)
+				{
+					facep->setSize(0, 0);
+				}
+			}
 		}
 	}
 	
@@ -2183,15 +2189,20 @@ void LLVOAvatar::updateMeshData()
 				part_index-- ;
 			}
 		
-			LLFace* facep ;
+			LLFace* facep = NULL;
 			if(f_num < mDrawable->getNumFaces()) 
 			{
 				facep = mDrawable->getFace(f_num);
 			}
 			else
 			{
-				facep = mDrawable->addFace(mDrawable->getFace(0)->getPool(), mDrawable->getFace(0)->getTexture()) ;
+				facep = mDrawable->getFace(0);
+				if (facep)
+				{
+					facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ;
+				}
 			}
+			if (!facep) continue;
 			
 			// resize immediately
 			facep->setSize(num_vertices, num_indices);
@@ -4236,10 +4247,14 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 			mNeedsSkin = FALSE;
 			mLastSkinTime = gFrameTimeSeconds;
 
-			LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer();
-			if (vb)
+			LLFace * face = mDrawable->getFace(0);
+			if (face)
 			{
-				vb->flush();
+				LLVertexBuffer* vb = face->getVertexBuffer();
+				if (vb)
+				{
+					vb->flush();
+				}
 			}
 		}
 	}
@@ -7492,7 +7507,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 			}
 
 			U32 gl_name;
-			LLImageGL::generateTextures(1, &gl_name );
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name );
 			stop_glerror();
 
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
@@ -7529,7 +7544,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 						maskData->mLastDiscardLevel = discard_level;
 						if (self->mBakedTextureDatas[baked_index].mMaskTexName)
 						{
-							LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
+							LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
 						}
 						self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
 						found_texture_id = true;
@@ -8395,7 +8410,7 @@ BOOL LLVOAvatar::updateLOD()
 	BOOL res = updateJointLODs();
 
 	LLFace* facep = mDrawable->getFace(0);
-	if (!facep->getVertexBuffer())
+	if (!facep || !facep->getVertexBuffer())
 	{
 		dirtyMesh(2);
 	}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index d2609e5587226a5103b08d3deefc4491e3951506..98f7245f8d1d4d79c078c6e9b4357caca3736c83 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2751,7 +2751,7 @@ void LLVOAvatarSelf::deleteScratchTextures()
 		 namep; 
 		 namep = sScratchTexNames.getNextData() )
 	{
-		LLImageGL::deleteTextures(1, (U32 *)namep );
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep );
 		stop_glerror();
 	}
 
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 8a79d564d3a3dfd7dfdbe65958e0559c51713804..44968342bf0fc430ecee93fbe229d3859e57b353 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -34,6 +34,7 @@
 #include "llagentcamera.h"
 #include "llnotificationsutil.h"
 #include "lldrawable.h"
+#include "lldrawpoolalpha.h"
 #include "llface.h"
 #include "llsky.h"
 #include "llsurface.h"
@@ -380,8 +381,10 @@ BOOL LLVOGrass::updateLOD()
 		{
 			mNumBlades <<= 1;
 		}
-
-		face->setSize(mNumBlades*8, mNumBlades*12);
+		if (face)
+		{
+			face->setSize(mNumBlades*8, mNumBlades*12);
+		}
 		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
 	}
 	else if (num_blades <= (mNumBlades >> 1))
@@ -391,7 +394,10 @@ BOOL LLVOGrass::updateLOD()
 			mNumBlades >>=1;
 		}
 
-		face->setSize(mNumBlades*8, mNumBlades*12);
+		if (face)
+		{
+			face->setSize(mNumBlades*8, mNumBlades*12);
+		}
 		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
 		return TRUE;
 	}
@@ -449,14 +455,16 @@ void LLVOGrass::plantBlades()
 	}
 		
 	LLFace *face = mDrawable->getFace(0);
+	if (face)
+	{
+		face->setTexture(getTEImage(0));
+		face->setState(LLFace::GLOBAL);
+		face->setSize(mNumBlades * 8, mNumBlades * 12);
+		face->setVertexBuffer(NULL);
+		face->setTEOffset(0);
+		face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
+	}
 
-	face->setTexture(getTEImage(0));
-	face->setState(LLFace::GLOBAL);
-	face->setSize(mNumBlades * 8, mNumBlades * 12);
-	face->setVertexBuffer(NULL);
-	face->setTEOffset(0);
-	face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
-	
 	mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();
 	mDrawable->setPosition(face->mCenterLocal);
 	mDrawable->movePartition();
@@ -486,6 +494,8 @@ void LLVOGrass::getGeometry(S32 idx,
 	LLColor4U color(255,255,255,255);
 
 	LLFace *face = mDrawable->getFace(idx);
+	if (!face)
+		return;
 
 	F32 width  = sSpeciesTable[mSpecies]->mBladeSizeX;
 	F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
@@ -594,6 +604,7 @@ U32 LLVOGrass::getPartitionType() const
 }
 
 LLGrassPartition::LLGrassPartition()
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
 {
 	mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
 	mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -604,6 +615,143 @@ LLGrassPartition::LLGrassPartition()
 	mBufferUsage = GL_DYNAMIC_DRAW_ARB;
 }
 
+void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
+{
+	group->mBufferUsage = mBufferUsage;
+
+	mFaceList.clear();
+
+	LLViewerCamera* camera = LLViewerCamera::getInstance();
+	for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+	{
+		LLDrawable* drawablep = *i;
+		
+		if (drawablep->isDead())
+		{
+			continue;
+		}
+
+		LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
+		obj->mDepth = 0.f;
+		
+		if (drawablep->isAnimating())
+		{
+			group->mBufferUsage = GL_STREAM_DRAW_ARB;
+		}
+
+		U32 count = 0;
+		for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
+		{
+			drawablep->updateFaceSize(j);
+
+			LLFace* facep = drawablep->getFace(j);
+			if ( !facep || !facep->hasGeometry())
+			{
+				continue;
+			}
+			
+			if ((facep->getGeomCount() + vertex_count) <= 65536)
+			{
+				count++;
+				facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
+				obj->mDepth += facep->mDistance;
+			
+				mFaceList.push_back(facep);
+				vertex_count += facep->getGeomCount();
+				index_count += facep->getIndicesCount();
+				llassert(facep->getIndicesCount() < 65536);
+			}
+			else
+			{
+				facep->clearVertexBuffer();
+			}
+		}
+		
+		obj->mDepth /= count;
+	}
+}
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
+
+void LLGrassPartition::getGeometry(LLSpatialGroup* group)
+{
+	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
+	LLFastTimer ftm(FTM_REBUILD_GRASS_VB);
+
+	std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
+
+	U32 index_count = 0;
+	U32 vertex_count = 0;
+
+	group->clearDrawMap();
+
+	LLVertexBuffer* buffer = group->mVertexBuffer;
+
+	LLStrider<U16> indicesp;
+	LLStrider<LLVector4a> verticesp;
+	LLStrider<LLVector3> normalsp;
+	LLStrider<LLVector2> texcoordsp;
+	LLStrider<LLColor4U> colorsp;
+
+	buffer->getVertexStrider(verticesp);
+	buffer->getNormalStrider(normalsp);
+	buffer->getColorStrider(colorsp);
+	buffer->getTexCoord0Strider(texcoordsp);
+	buffer->getIndexStrider(indicesp);
+
+	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];	
+
+	for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
+	{
+		LLFace* facep = *i;
+		LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
+		facep->setGeomIndex(vertex_count);
+		facep->setIndicesIndex(index_count);
+		facep->setVertexBuffer(buffer);
+		facep->setPoolType(LLDrawPool::POOL_ALPHA);
+		object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+		
+		vertex_count += facep->getGeomCount();
+		index_count += facep->getIndicesCount();
+
+		S32 idx = draw_vec.size()-1;
+
+		BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
+		F32 vsize = facep->getVirtualSize();
+
+		if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+			draw_vec[idx]->mTexture == facep->getTexture() &&
+			(U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
+			//draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
+			draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
+			draw_vec[idx]->mFullbright == fullbright)
+		{
+			draw_vec[idx]->mCount += facep->getIndicesCount();
+			draw_vec[idx]->mEnd += facep->getGeomCount();
+			draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+		}
+		else
+		{
+			U32 start = facep->getGeomIndex();
+			U32 end = start + facep->getGeomCount()-1;
+			U32 offset = facep->getIndicesStart();
+			U32 count = facep->getIndicesCount();
+			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), 
+				//facep->getTexture(),
+				buffer, fullbright); 
+			info->mExtents[0] = group->mObjectExtents[0];
+			info->mExtents[1] = group->mObjectExtents[1];
+			info->mVSize = vsize;
+			draw_vec.push_back(info);
+			//for alpha sorting
+			facep->setDrawInfo(info);
+		}
+	}
+
+	buffer->flush();
+	mFaceList.clear();
+}
+
 // virtual
 void LLVOGrass::updateDrawable(BOOL force_damped)
 {
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 0060f81ab5043f5235b6b1fd0ae03e868c9a515a..6da54435e3ca9904686f5d832d5527678c930ba0 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -82,6 +82,7 @@ LLDrawable *LLVOGround::createDrawable(LLPipeline *pipeline)
 	return mDrawable;
 }
 
+// TO DO - this always returns TRUE, 
 BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
 {
 	LLStrider<LLVector3> verticesp;
@@ -96,6 +97,8 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
 	if (drawable->getNumFaces() < 1)
 		drawable->addFace(poolp, NULL);
 	face = drawable->getFace(0); 
+	if (!face)
+		return TRUE;
 		
 	if (!face->getVertexBuffer())
 	{
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 5c10a80b07380af65c80c7e7f57bd713261d0972..e21358b65a29638e18af95af7a5f5877969ba883 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -48,6 +48,117 @@ const F32 MAX_PART_LIFETIME = 120.f;
 
 extern U64 gFrameTime;
 
+LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
+S32 LLVOPartGroup::sVBSlotFree[];
+S32* LLVOPartGroup::sVBSlotCursor = NULL;
+
+//static
+void LLVOPartGroup::restoreGL()
+{
+	for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
+	{
+		sVBSlotFree[i] = i;
+	}
+
+	sVBSlotCursor = sVBSlotFree;
+
+	sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+	U32 count = LL_MAX_PARTICLE_COUNT;
+	sVB->allocateBuffer(count*4, count*6, true);
+
+	//indices and texcoords are always the same, set once
+	LLStrider<U16> indicesp;
+
+	LLStrider<LLVector4a> verticesp;
+
+	sVB->getIndexStrider(indicesp);
+	sVB->getVertexStrider(verticesp);
+
+	LLVector4a v;
+	v.set(0,0,0,0);
+
+	
+	U16 vert_offset = 0;
+
+	for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+	{
+		*indicesp++ = vert_offset + 0;
+		*indicesp++ = vert_offset + 1;
+		*indicesp++ = vert_offset + 2;
+
+		*indicesp++ = vert_offset + 1;
+		*indicesp++ = vert_offset + 3;
+		*indicesp++ = vert_offset + 2;
+
+		*verticesp++ = v;
+
+		vert_offset += 4;
+	}
+
+	LLStrider<LLVector2> texcoordsp;
+	sVB->getTexCoord0Strider(texcoordsp);
+
+	for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+	{
+		*texcoordsp++ = LLVector2(0.f, 1.f);
+		*texcoordsp++ = LLVector2(0.f, 0.f);
+		*texcoordsp++ = LLVector2(1.f, 1.f);
+		*texcoordsp++ = LLVector2(1.f, 0.f);
+	}
+
+	sVB->flush();
+
+}
+
+//static
+void LLVOPartGroup::destroyGL()
+{
+	sVB = NULL;
+}
+
+//static
+S32 LLVOPartGroup::findAvailableVBSlot()
+{
+	if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT)
+	{ //no more available slots
+		return -1;
+	}
+
+	S32 ret = *sVBSlotCursor;
+	sVBSlotCursor++;
+
+	return ret;
+}
+
+bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
+{
+	while (start < end)
+	{
+		if (*start == idx)
+		{ //not allocated (in free list)
+			return false;
+		}
+		++start;
+	}
+
+	//allocated (not in free list)
+	return true;
+}
+
+//static
+void LLVOPartGroup::freeVBSlot(S32 idx)
+{
+	llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
+	llassert(sVBSlotCursor > sVBSlotFree);
+	llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
+
+	if (sVBSlotCursor > sVBSlotFree)
+	{
+		sVBSlotCursor--;
+		*sVBSlotCursor = idx;
+	}
+}
+
 LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 	:	LLAlphaObject(id, pcode, regionp),
 		mViewerPartGroupp(NULL)
@@ -62,7 +173,6 @@ LLVOPartGroup::~LLVOPartGroup()
 {
 }
 
-
 BOOL LLVOPartGroup::isActive() const
 {
 	return FALSE;
@@ -287,9 +397,6 @@ void LLVOPartGroup::getGeometry(S32 idx,
 
 	const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
 
-	U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
-
-	
 	LLVector4a part_pos_agent;
 	part_pos_agent.load3(part.mPosAgent.mV);
 	LLVector4a camera_agent;
@@ -361,33 +468,18 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	verticesp->setAdd(ppamu, right);
 	(*verticesp++).getF32ptr()[3] = 0.f;
 
-	//*verticesp++ = part_pos_agent + up - right;
-	//*verticesp++ = part_pos_agent - up - right;
-	//*verticesp++ = part_pos_agent + up + right;
-	//*verticesp++ = part_pos_agent - up + right;
-
 	*colorsp++ = part.mColor;
 	*colorsp++ = part.mColor;
 	*colorsp++ = part.mColor;
 	*colorsp++ = part.mColor;
 
-	*texcoordsp++ = LLVector2(0.f, 1.f);
-	*texcoordsp++ = LLVector2(0.f, 0.f);
-	*texcoordsp++ = LLVector2(1.f, 1.f);
-	*texcoordsp++ = LLVector2(1.f, 0.f);
-
-	*normalsp++   = normal;
-	*normalsp++   = normal;
-	*normalsp++   = normal;
-	*normalsp++   = normal;
-
-	*indicesp++ = vert_offset + 0;
-	*indicesp++ = vert_offset + 1;
-	*indicesp++ = vert_offset + 2;
-
-	*indicesp++ = vert_offset + 1;
-	*indicesp++ = vert_offset + 3;
-	*indicesp++ = vert_offset + 2;
+	if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
+	{ //not fullbright, needs normal
+		*normalsp++   = normal;
+		*normalsp++   = normal;
+		*normalsp++   = normal;
+		*normalsp++   = normal;
+	}
 }
 
 U32 LLVOPartGroup::getPartitionType() const
@@ -412,6 +504,49 @@ LLHUDParticlePartition::LLHUDParticlePartition() :
 	mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
 }
 
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");
+
+void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
+{
+	if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
+	{
+		return;
+	}
+
+	if (group->changeLOD())
+	{
+		group->mLastUpdateDistance = group->mDistance;
+		group->mLastUpdateViewAngle = group->mViewAngle;
+	}
+	
+	LLFastTimer ftm(FTM_REBUILD_PARTICLE_VBO);	
+
+	group->clearDrawMap();
+	
+	//get geometry count
+	U32 index_count = 0;
+	U32 vertex_count = 0;
+
+	addGeometryCount(group, vertex_count, index_count);
+	
+
+	if (vertex_count > 0 && index_count > 0)
+	{ 
+		group->mBuilt = 1.f;
+		//use one vertex buffer for all groups
+		group->mVertexBuffer = LLVOPartGroup::sVB;
+		getGeometry(group);
+	}
+	else
+	{
+		group->mVertexBuffer = NULL;
+		group->mBufferMap.clear();
+	}
+
+	group->mLastUpdateTime = gFrameTimeSeconds;
+	group->clearState(LLSpatialGroup::GEOM_DIRTY);
+}
+
 void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
 {
 	group->mBufferUsage = mBufferUsage;
@@ -431,11 +566,6 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
 		LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
 		obj->mDepth = 0.f;
 		
-		if (drawablep->isAnimating())
-		{
-			group->mBufferUsage = GL_STREAM_DRAW_ARB;
-		}
-
 		U32 count = 0;
 		for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
 		{
@@ -447,13 +577,14 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
 				continue;
 			}
 			
+			vertex_count += facep->getGeomCount();
+			index_count += facep->getIndicesCount();
+
 			count++;
 			facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
 			obj->mDepth += facep->mDistance;
 			
 			mFaceList.push_back(facep);
-			vertex_count += facep->getGeomCount();
-			index_count += facep->getIndicesCount();
 			llassert(facep->getIndicesCount() < 65536);
 		}
 		
@@ -461,15 +592,13 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
 	}
 }
 
-static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
-static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB");
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_GEOM("Particle Geom");
 
 void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 {
 	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-	LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
-					FTM_REBUILD_GRASS_VB :
-					FTM_REBUILD_PARTICLE_VB);
+	LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);
 
 	std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
 
@@ -489,21 +618,44 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 	buffer->getVertexStrider(verticesp);
 	buffer->getNormalStrider(normalsp);
 	buffer->getColorStrider(colorsp);
-	buffer->getTexCoord0Strider(texcoordsp);
-	buffer->getIndexStrider(indicesp);
-
+	
 	LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];	
 
 	for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
 	{
 		LLFace* facep = *i;
 		LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
-		facep->setGeomIndex(vertex_count);
-		facep->setIndicesIndex(index_count);
-		facep->setVertexBuffer(buffer);
-		facep->setPoolType(LLDrawPool::POOL_ALPHA);
-		object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+
+		if (facep->getIndicesStart() == 0xFFFFFFFF)
+		{ //set the indices of this face
+			S32 idx = LLVOPartGroup::findAvailableVBSlot();
+			if (idx >= 0)
+			{
+				facep->setGeomIndex(idx*4);
+				facep->setIndicesIndex(idx*6);
+				facep->setVertexBuffer(LLVOPartGroup::sVB);
+				facep->setPoolType(LLDrawPool::POOL_ALPHA);
+			}
+			else
+			{
+				continue; //out of space in particle buffer
+			}		
+		}
+
+		S32 geom_idx = (S32) facep->getGeomIndex();
+
+		LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart();
+		LLStrider<LLVector4a> cur_vert = verticesp + geom_idx;
+		LLStrider<LLVector3> cur_norm = normalsp + geom_idx;
+		LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;
+		LLStrider<LLColor4U> cur_col = colorsp + geom_idx;
+
+		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx);
 		
+		llassert(facep->getGeomCount() == 4);
+		llassert(facep->getIndicesCount() == 6);
+
+
 		vertex_count += facep->getGeomCount();
 		index_count += facep->getIndicesCount();
 
@@ -512,18 +664,31 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 		BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
 		F32 vsize = facep->getVirtualSize();
 
-		if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+		bool batched = false;
+	
+		if (idx >= 0 &&
 			draw_vec[idx]->mTexture == facep->getTexture() &&
-			(U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
-			//draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
-			draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
 			draw_vec[idx]->mFullbright == fullbright)
 		{
-			draw_vec[idx]->mCount += facep->getIndicesCount();
-			draw_vec[idx]->mEnd += facep->getGeomCount();
-			draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+			if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
+			{
+				batched = true;
+				draw_vec[idx]->mCount += facep->getIndicesCount();
+				draw_vec[idx]->mEnd += facep->getGeomCount();
+				draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+			}
+			else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+			{
+				batched = true;
+				draw_vec[idx]->mCount += facep->getIndicesCount();
+				draw_vec[idx]->mStart -= facep->getGeomCount();
+				draw_vec[idx]->mOffset = facep->getIndicesStart();
+				draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+			}
 		}
-		else
+
+
+		if (!batched)
 		{
 			U32 start = facep->getGeomIndex();
 			U32 end = start + facep->getGeomCount()-1;
@@ -541,7 +706,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 		}
 	}
 
-	buffer->flush();
 	mFaceList.clear();
 }
 
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index e58fed86d969ff10d55bf800d3d3bdc1ee306ac4..6160bceb24a867e869b865086e02391bf6e66c33 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -31,18 +31,32 @@
 #include "v3math.h"
 #include "v3color.h"
 #include "llframetimer.h"
+#include "llviewerpartsim.h"
+#include "llvertexbuffer.h"
 
 class LLViewerPartGroup;
 
 class LLVOPartGroup : public LLAlphaObject
 {
 public:
+
+	//vertex buffer for holding all particles
+	static LLPointer<LLVertexBuffer> sVB;
+	static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
+	static S32* sVBSlotCursor;
+
+	static void restoreGL();
+	static void destroyGL();
+	static S32 findAvailableVBSlot();
+	static void freeVBSlot(S32 idx);
+
 	enum
 	{
-		VERTEX_DATA_MASK =	(1 << LLVertexBuffer::TYPE_VERTEX) |
-							(1 << LLVertexBuffer::TYPE_NORMAL) |
-							(1 << LLVertexBuffer::TYPE_TEXCOORD0) |
-							(1 << LLVertexBuffer::TYPE_COLOR)
+		VERTEX_DATA_MASK =	LLVertexBuffer::MAP_VERTEX |
+							LLVertexBuffer::MAP_NORMAL |
+							LLVertexBuffer::MAP_TEXCOORD0 |
+							LLVertexBuffer::MAP_COLOR |
+							LLVertexBuffer::MAP_TEXTURE_INDEX
 	};
 
 	LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index bf6158eeafff8ade246ff261820a1806bcfc62cd..94a3111f4cb6e06eefae11518f6a38265f0fd89b 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -296,18 +296,20 @@ void LLVOSurfacePatch::updateFaceSize(S32 idx)
 	}
 
 	LLFace* facep = mDrawable->getFace(idx);
-
-	S32 num_vertices = 0;
-	S32 num_indices = 0;
-	
-	if (mLastStride)
+	if (facep)
 	{
-		getGeomSizesMain(mLastStride, num_vertices, num_indices);
-		getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
-		getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
-	}
+		S32 num_vertices = 0;
+		S32 num_indices = 0;
+	
+		if (mLastStride)
+		{
+			getGeomSizesMain(mLastStride, num_vertices, num_indices);
+			getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
+			getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
+		}
 
-	facep->setSize(num_vertices, num_indices);	
+		facep->setSize(num_vertices, num_indices);	
+	}
 }
 
 BOOL LLVOSurfacePatch::updateLOD()
@@ -322,30 +324,32 @@ void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
 								LLStrider<U16> &indicesp)
 {
 	LLFace* facep = mDrawable->getFace(0);
+	if (facep)
+	{
+		U32 index_offset = facep->getGeomIndex();
 
-	U32 index_offset = facep->getGeomIndex();
-
-	updateMainGeometry(facep, 
-					verticesp,
-					normalsp,
-					texCoords0p,
-					texCoords1p,
-					indicesp,
-					index_offset);
-	updateNorthGeometry(facep, 
-						verticesp,
-						normalsp,
-						texCoords0p,
-						texCoords1p,
-						indicesp,
-						index_offset);
-	updateEastGeometry(facep, 
+		updateMainGeometry(facep, 
 						verticesp,
 						normalsp,
 						texCoords0p,
 						texCoords1p,
 						indicesp,
 						index_offset);
+		updateNorthGeometry(facep, 
+							verticesp,
+							normalsp,
+							texCoords0p,
+							texCoords1p,
+							indicesp,
+							index_offset);
+		updateEastGeometry(facep, 
+							verticesp,
+							normalsp,
+							texCoords0p,
+							texCoords1p,
+							indicesp,
+							index_offset);
+	}
 }
 
 void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
@@ -864,7 +868,11 @@ void LLVOSurfacePatch::dirtyGeom()
 	if (mDrawable)
 	{
 		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
-		mDrawable->getFace(0)->setVertexBuffer(NULL);
+		LLFace* facep = mDrawable->getFace(0);
+		if (facep)
+		{
+			facep->setVertexBuffer(NULL);
+		}
 		mDrawable->movePartition();
 	}
 }
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 4564207da4d4d2becc4b82aedb3e82e82a7acf47..3556bde9a87843f13b6c69220f5a2e7b7045d082 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -490,11 +490,16 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
 	if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree.
 	{
 		mReferenceBuffer = NULL ;
-		mDrawable->getFace(0)->setVertexBuffer(NULL);
+		LLFace * facep = drawable->getFace(0);
+		if (facep)
+		{
+			facep->setVertexBuffer(NULL);
+		}
 		return TRUE ;
 	}
 
-	if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer())
+	if (mDrawable->getFace(0) &&
+		(mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()))
 	{
 		const F32 SRR3 = 0.577350269f; // sqrt(1/3)
 		const F32 SRR2 = 0.707106781f; // sqrt(1/2)
@@ -507,6 +512,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
 		S32 lod;
 
 		LLFace *face = drawable->getFace(0);
+		if (!face) return TRUE;
 
 		face->mCenterAgent = getPositionAgent();
 		face->mCenterLocal = face->mCenterAgent;
@@ -879,6 +885,7 @@ void LLVOTree::updateMesh()
 	calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches);
 
 	LLFace* facep = mDrawable->getFace(0);
+	if (!facep) return;
 	LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
 	buff->allocateBuffer(vert_count, index_count, TRUE);
 	facep->setVertexBuffer(buff);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 080d1f774a0cb4417f4af93533066a0cecb54291..c4e7ea44b4022c8537a47d65319630be3b5cc4aa 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -520,6 +520,7 @@ void LLVOVolume::animateTextures()
 		for (S32 i = start; i <= end; i++)
 		{
 			LLFace* facep = mDrawable->getFace(i);
+			if (!facep) continue;
 			if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
 
 			const LLTextureEntry* te = facep->getTextureEntry();
@@ -638,7 +639,7 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 {
 	LLViewerObject::idleUpdate(agent, world, time);
 
-	static LLFastTimer::DeclareTimer ftm("Volume");
+	static LLFastTimer::DeclareTimer ftm("Volume Idle");
 	LLFastTimer t(ftm);
 
 	if (mDead || mDrawable.isNull())
@@ -682,7 +683,21 @@ void LLVOVolume::updateTextures()
 	const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
 	if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
 	{
-		updateTextureVirtualSize();		
+		updateTextureVirtualSize();
+
+		if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
+		{ //delete vertex buffer to free up some VRAM
+			LLSpatialGroup* group  = mDrawable->getSpatialGroup();
+			if (group)
+			{
+				group->destroyGL(true);
+
+				//flag the group as having changed geometry so it gets a rebuild next time
+				//it becomes visible
+				group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+			}
+		}
+
 	}
 }
 
@@ -715,7 +730,18 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 	if(!forced)
 	{
 		if(!isVisible())
-		{
+		{ //don't load textures for non-visible faces
+			const S32 num_faces = mDrawable->getNumFaces();
+			for (S32 i = 0; i < num_faces; i++)
+			{
+				LLFace* face = mDrawable->getFace(i);
+				if (face)
+				{
+					face->setPixelArea(0.f); 
+					face->setVirtualSize(0.f);
+				}
+			}
+
 			return ;
 		}
 
@@ -743,6 +769,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 	for (S32 i = 0; i < num_faces; i++)
 	{
 		LLFace* face = mDrawable->getFace(i);
+		if (!face) continue;
 		const LLTextureEntry *te = face->getTextureEntry();
 		LLViewerTexture *imagep = face->getTexture();
 		if (!imagep || !te ||			
@@ -1062,9 +1089,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 			}
 		}
 
+
+		static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+		bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
+			(!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
+
+		if (cache_in_vram)
+		{ //this volume might be used as source data for a transform object, put it in vram
+			LLVolume* volume = getVolume();
+			for (S32 i = 0; i < volume->getNumFaces(); ++i)
+			{
+				const LLVolumeFace& face = volume->getVolumeFace(i);
+				if (face.mVertexBuffer.notNull())
+				{ //already cached
+					break;
+				}
+				volume->genBinormals(i);
+				LLFace::cacheFaceInVRAM(face);
+			}
+		}
+		
+
 		return TRUE;
 	}
 
+
+
 	return FALSE;
 }
 
@@ -1246,7 +1297,8 @@ BOOL LLVOVolume::calcLOD()
 									llround(radius, 0.01f));
 
 
-	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))
+	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
+		mDrawable->getFace(0))
 	{
 		//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail));
 
@@ -1325,25 +1377,23 @@ void LLVOVolume::updateFaceFlags()
 	for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
 	{
 		LLFace *face = mDrawable->getFace(i);
-		if (!face)
+		if (face)
 		{
-			return;
-		}
+			BOOL fullbright = getTE(i)->getFullbright();
+			face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
 
-		BOOL fullbright = getTE(i)->getFullbright();
-		face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
-
-		if (fullbright || (mMaterial == LL_MCODE_LIGHT))
-		{
-			face->setState(LLFace::FULLBRIGHT);
-		}
-		if (mDrawable->isLight())
-		{
-			face->setState(LLFace::LIGHT);
-		}
-		if (isHUDAttachment())
-		{
-			face->setState(LLFace::HUD_RENDER);
+			if (fullbright || (mMaterial == LL_MCODE_LIGHT))
+			{
+				face->setState(LLFace::FULLBRIGHT);
+			}
+			if (mDrawable->isLight())
+			{
+				face->setState(LLFace::LIGHT);
+			}
+			if (isHUDAttachment())
+			{
+				face->setState(LLFace::HUD_RENDER);
+			}
 		}
 	}
 }
@@ -1380,6 +1430,8 @@ void LLVOVolume::regenFaces()
 	for (S32 i = 0; i < mNumFaces; i++)
 	{
 		LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
+		if (!facep) continue;
+
 		facep->setTEOffset(i);
 		facep->setTexture(getTEImage(i));
 		facep->setViewerObject(this);
@@ -1416,7 +1468,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
 
 	BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED);
 
-//	bool rigged = false;
+	//	bool rigged = false;
 	LLVolume* volume = mRiggedVolume;
 	if (!volume)
 	{
@@ -1471,11 +1523,11 @@ void LLVOVolume::preRebuild()
 	}
 }
 
-void LLVOVolume::updateRelativeXform()
+void LLVOVolume::updateRelativeXform(bool force_identity)
 {
 	if (mVolumeImpl)
 	{
-		mVolumeImpl->updateRelativeXform();
+		mVolumeImpl->updateRelativeXform(force_identity);
 		return;
 	}
 	
@@ -1495,15 +1547,16 @@ void LLVOVolume::updateRelativeXform()
 		mRelativeXform.invert();
 		mRelativeXformInvTrans.transpose();
 	}
-	else if (drawable->isActive())
+	else if (drawable->isActive() || force_identity)
 	{				
 		// setup relative transforms
 		LLQuaternion delta_rot;
 		LLVector3 delta_pos, delta_scale;
 		
 		//matrix from local space to parent relative/global space
-		delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation();
-		delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition();
+		bool use_identity = force_identity || drawable->isSpatialRoot();
+		delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation();
+		delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();
 		delta_scale = mDrawable->getScale();
 
 		// Vertex transform (4x4)
@@ -1604,7 +1657,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
 		return res;
 	}
 	
-	dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+	LLSpatialGroup* group = drawable->getSpatialGroup();
+	if (group)
+	{
+		group->dirtyMesh();
+	}
 
 	BOOL compiled = FALSE;
 			
@@ -1617,6 +1674,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
 
 	if (mVolumeChanged || mFaceMappingChanged )
 	{
+		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
 		compiled = TRUE;
 
 		if (mVolumeChanged)
@@ -1635,6 +1694,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
 	}
 	else if ((mLODChanged) || (mSculptChanged))
 	{
+		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
 		LLVolume *old_volumep, *new_volumep;
 		F32 old_lod, new_lod;
 		S32 old_num_faces, new_num_faces ;
@@ -1716,16 +1777,19 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
 void LLVOVolume::updateFaceSize(S32 idx)
 {
 	LLFace* facep = mDrawable->getFace(idx);
-	if (idx >= getVolume()->getNumVolumeFaces())
-	{
-		facep->setSize(0,0, true);
-	}
-	else
+	if (facep)
 	{
-		const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
-		facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, 
-						true); // <--- volume faces should be padded for 16-byte alignment
+		if (idx >= getVolume()->getNumVolumeFaces())
+		{
+			facep->setSize(0,0, true);
+		}
+		else
+		{
+			const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
+			facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, 
+							true); // <--- volume faces should be padded for 16-byte alignment
 		
+		}
 	}
 }
 
@@ -3098,6 +3162,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
 	for (S32 i = 0; i < num_faces; ++i)
 	{
 		const LLFace* face = drawablep->getFace(i);
+		if (!face) continue;
 		const LLTextureEntry* te = face->getTextureEntry();
 		const LLViewerTexture* img = face->getTexture();
 
@@ -3369,6 +3434,7 @@ F32 LLVOVolume::getBinRadius()
 		for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
 		{
 			LLFace* face = mDrawable->getFace(i);
+			if (!face) continue;
 			if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
 			    !face->canRenderAsMask())
 			{
@@ -3450,9 +3516,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const
 {
 	LLVector3 ret = pos - getRenderPosition();
 	ret = ret * ~getRenderRotation();
-	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
-	LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
-	ret.scaleVec(invObjScale);
+	if (!isVolumeGlobal())
+	{
+		LLVector3 objScale = getScale();
+		LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+		ret.scaleVec(invObjScale);
+	}
 	
 	return ret;
 }
@@ -3470,8 +3539,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const
 LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const
 {
 	LLVector3 ret = dir;
-	LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
-	ret.scaleVec(objScale);
+	if (!isVolumeGlobal())
+	{
+		LLVector3 objScale = getScale();
+		ret.scaleVec(objScale);
+	}
+
 	ret = ret * getRenderRotation();
 	ret += getRenderPosition();
 	
@@ -3592,7 +3665,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
 			{
 				LLFace* face = mDrawable->getFace(face_hit);				
 
-				if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
+				if (face &&
+					(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
 				{
 					v_end = p;
 					if (face_hitp != NULL)
@@ -3902,8 +3976,11 @@ bool can_batch_texture(LLFace* facep)
 	return true;
 }
 
+static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");
+
 void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
 {
+	LLFastTimer t(FTM_REGISTER_FACE);
 	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
 
 	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
@@ -3935,9 +4012,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 	const LLMatrix4* model_mat = NULL;
 
 	LLDrawable* drawable = facep->getDrawable();
-	if (drawable->isActive())
+	
+	if (drawable->isState(LLDrawable::ANIMATED_CHILD))
+	{
+		model_mat = &drawable->getWorldMatrix();
+	}
+	else if (drawable->isActive())
 	{
-		model_mat = &(drawable->getRenderMatrix());
+		model_mat = &drawable->getRenderMatrix();
 	}
 	else
 	{
@@ -3948,6 +4030,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		}
 	}
 
+	//drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
+
 	U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
 	
 	LLViewerTexture* tex = facep->getTexture();
@@ -4041,8 +4125,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
 
 }
 
-static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
-static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info");
 
 static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
 {
@@ -4073,6 +4158,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
 
 void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 {
+	
+
 	if (group->changeLOD())
 	{
 		group->mLastUpdateDistance = group->mDistance;
@@ -4084,19 +4171,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 	{
 		if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
 		{
-			LLFastTimer ftm(FTM_REBUILD_VBO);	
-			LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
-		
 			rebuildMesh(group);
 		}
 		return;
 	}
 
-	group->mBuilt = 1.f;
-	LLFastTimer ftm(FTM_REBUILD_VBO);	
-
-	LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
+	LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
 
+	group->mBuilt = 1.f;
+	
 	LLVOAvatar* pAvatarVO = NULL;
 
 	LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
@@ -4145,359 +4228,375 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 	bool emissive = false;
 
-	//get all the faces into a list
-	for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
 	{
-		LLDrawable* drawablep = *drawable_iter;
-		
-		if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+		LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST);
+
+		//get all the faces into a list
+		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
 		{
-			continue;
-		}
+			LLDrawable* drawablep = *drawable_iter;
+		
+			if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+			{
+				continue;
+			}
 	
-		if (drawablep->isAnimating())
-		{ //fall back to stream draw for animating verts
-			useage = GL_STREAM_DRAW_ARB;
-		}
+			if (drawablep->isAnimating())
+			{ //fall back to stream draw for animating verts
+				useage = GL_STREAM_DRAW_ARB;
+			}
 
-		LLVOVolume* vobj = drawablep->getVOVolume();
+			LLVOVolume* vobj = drawablep->getVOVolume();
 
-		if (!vobj)
-		{
-			continue;
-		}
+			if (!vobj)
+			{
+				continue;
+			}
 
-		if (vobj->isMesh() &&
-			(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
-		{
-			continue;
-		}
+			if (vobj->isMesh() &&
+				(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
+			{
+				continue;
+			}
 
-		LLVolume* volume = vobj->getVolume();
-		if (volume)
-		{
-			const LLVector3& scale = vobj->getScale();
-			group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
-		}
+			LLVolume* volume = vobj->getVolume();
+			if (volume)
+			{
+				const LLVector3& scale = vobj->getScale();
+				group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
+			}
 
-		llassert_always(vobj);
-		vobj->updateTextureVirtualSize(true);
-		vobj->preRebuild();
+			llassert_always(vobj);
+			vobj->updateTextureVirtualSize(true);
+			vobj->preRebuild();
 
-		drawablep->clearState(LLDrawable::HAS_ALPHA);
+			drawablep->clearState(LLDrawable::HAS_ALPHA);
 
-		bool rigged = vobj->isAttachment() && 
-					vobj->isMesh() && 
-					gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
+			bool rigged = vobj->isAttachment() && 
+						vobj->isMesh() && 
+						gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
 
-		bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
+			bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
 
-		bool is_rigged = false;
+			bool is_rigged = false;
 
-		//for each face
-		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
-		{
-			LLFace* facep = drawablep->getFace(i);
+			//for each face
+			for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+			{
+				LLFace* facep = drawablep->getFace(i);
+				if (!facep)
+				{
+					continue;
+				}
 
-			//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
-			// batch, it will recover its vertex buffer reference from the spatial group
-			facep->setVertexBuffer(NULL);
+				//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
+				// batch, it will recover its vertex buffer reference from the spatial group
+				facep->setVertexBuffer(NULL);
 			
-			//sum up face verts and indices
-			drawablep->updateFaceSize(i);
+				//sum up face verts and indices
+				drawablep->updateFaceSize(i);
 			
 			
 
-			if (rigged) 
-			{
-				if (!facep->isState(LLFace::RIGGED))
-				{ //completely reset vertex buffer
-					facep->clearVertexBuffer();
-				}
+				if (rigged) 
+				{
+					if (!facep->isState(LLFace::RIGGED))
+					{ //completely reset vertex buffer
+						facep->clearVertexBuffer();
+					}
 		
-				facep->setState(LLFace::RIGGED);
-				is_rigged = true;
+					facep->setState(LLFace::RIGGED);
+					is_rigged = true;
 				
-				//get drawpool of avatar with rigged face
-				LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
+					//get drawpool of avatar with rigged face
+					LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
 				
-				//Determine if we've received skininfo that contains an
-				//alternate bind matrix - if it does then apply the translational component
-				//to the joints of the avatar.
-				bool pelvisGotSet = false;
+					//Determine if we've received skininfo that contains an
+					//alternate bind matrix - if it does then apply the translational component
+					//to the joints of the avatar.
+					bool pelvisGotSet = false;
 
-				if ( pAvatarVO )
-				{
-					LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
-					const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
-					
-					if ( pSkinData )
+					if ( pAvatarVO )
 					{
-						const int bindCnt = pSkinData->mAlternateBindMatrix.size();								
-						if ( bindCnt > 0 )
-						{					
-							const int jointCnt = pSkinData->mJointNames.size();
-							const F32 pelvisZOffset = pSkinData->mPelvisOffset;
-							bool fullRig = (jointCnt>=20) ? true : false;
-							if ( fullRig )
-							{
-								for ( int i=0; i<jointCnt; ++i )
+						LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+						const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+					
+						if ( pSkinData )
+						{
+							const int bindCnt = pSkinData->mAlternateBindMatrix.size();								
+							if ( bindCnt > 0 )
+							{					
+								const int jointCnt = pSkinData->mJointNames.size();
+								const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+								bool fullRig = (jointCnt>=20) ? true : false;
+								if ( fullRig )
 								{
-									std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
-									//llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
-									LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
-									if ( pJoint && pJoint->getId() != currentId )
-									{   									
-										pJoint->setId( currentId );
-										const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									
-										//Set the joint position
-										pJoint->storeCurrentXform( jointPos );																																
-										//If joint is a pelvis then handle old/new pelvis to foot values
-										if ( lookingForJoint == "mPelvis" )
-										{	
+									for ( int i=0; i<jointCnt; ++i )
+									{
+										std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+										//llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
+										LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
+										if ( pJoint && pJoint->getId() != currentId )
+										{   									
+											pJoint->setId( currentId );
+											const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									
+											//Set the joint position
 											pJoint->storeCurrentXform( jointPos );																																
-											if ( !pAvatarVO->hasPelvisOffset() )
-											{										
-												pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
-												//Trigger to rebuild viewer AV
-												pelvisGotSet = true;											
+											//If joint is a pelvis then handle old/new pelvis to foot values
+											if ( lookingForJoint == "mPelvis" )
+											{	
+												pJoint->storeCurrentXform( jointPos );																																
+												if ( !pAvatarVO->hasPelvisOffset() )
+												{										
+													pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
+													//Trigger to rebuild viewer AV
+													pelvisGotSet = true;											
+												}										
 											}										
-										}										
+										}
 									}
-								}
-							}							
+								}							
+							}
 						}
 					}
-				}
-				//If we've set the pelvis to a new position we need to also rebuild some information that the
-				//viewer does at launch (e.g. body size etc.)
-				if ( pelvisGotSet )
-				{
-					pAvatarVO->postPelvisSetRecalc();
-				}
-
-				if (pool)
-				{
-					const LLTextureEntry* te = facep->getTextureEntry();
-
-					//remove face from old pool if it exists
-					LLDrawPool* old_pool = facep->getPool();
-					if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+					//If we've set the pelvis to a new position we need to also rebuild some information that the
+					//viewer does at launch (e.g. body size etc.)
+					if ( pelvisGotSet )
 					{
-						((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+						pAvatarVO->postPelvisSetRecalc();
 					}
 
-					//add face to new pool
-					LLViewerTexture* tex = facep->getTexture();
-					U32 type = gPipeline.getPoolTypeFromTE(te, tex);
-
-					if (type == LLDrawPool::POOL_ALPHA)
+					if (pool)
 					{
-						if (te->getColor().mV[3] > 0.f)
+						const LLTextureEntry* te = facep->getTextureEntry();
+
+						//remove face from old pool if it exists
+						LLDrawPool* old_pool = facep->getPool();
+						if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+						{
+							((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+						}
+
+						//add face to new pool
+						LLViewerTexture* tex = facep->getTexture();
+						U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+
+						if (type == LLDrawPool::POOL_ALPHA)
+						{
+							if (te->getColor().mV[3] > 0.f)
+							{
+								if (te->getFullbright())
+								{
+									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+								}
+								else
+								{
+									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+								}
+							}
+						}
+						else if (te->getShiny())
 						{
 							if (te->getFullbright())
 							{
-								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
 							}
 							else
 							{
-								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+								if (LLPipeline::sRenderDeferred)
+								{
+									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+								}
+								else
+								{
+									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+								}
 							}
 						}
-					}
-					else if (te->getShiny())
-					{
-						if (te->getFullbright())
-						{
-							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
-						}
 						else
 						{
-							if (LLPipeline::sRenderDeferred)
+							if (te->getFullbright())
 							{
-								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
 							}
 							else
 							{
-								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
 							}
 						}
-					}
-					else
-					{
-						if (te->getFullbright())
-						{
-							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
-						}
-						else
+
+						if (te->getGlow())
 						{
-							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
 						}
-					}
 
-					if (te->getGlow())
-					{
-						pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
-					}
-
-					if (LLPipeline::sRenderDeferred)
-					{
-						if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+						if (LLPipeline::sRenderDeferred)
 						{
-							if (te->getBumpmap())
-							{
-								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
-							}
-							else
+							if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
 							{
-								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+								if (te->getBumpmap())
+								{
+									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+								}
+								else
+								{
+									pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+								}
 							}
 						}
 					}
-				}
 
-				continue;
-			}
-			else
-			{
-				if (facep->isState(LLFace::RIGGED))
-				{ //face is not rigged but used to be, remove from rigged face pool
-					LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
-					if (pool)
-					{
-						pool->removeRiggedFace(facep);
+					continue;
+				}
+				else
+				{
+					if (facep->isState(LLFace::RIGGED))
+					{ //face is not rigged but used to be, remove from rigged face pool
+						LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+						if (pool)
+						{
+							pool->removeRiggedFace(facep);
+						}
+						facep->clearState(LLFace::RIGGED);
 					}
-					facep->clearState(LLFace::RIGGED);
 				}
-			}
 
 
-			if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
-			{
-				facep->clearVertexBuffer();
-				continue;
-			}
-
-			cur_total += facep->getGeomCount();
-
-			if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
-			{
-				const LLTextureEntry* te = facep->getTextureEntry();
-				LLViewerTexture* tex = facep->getTexture();
-
-				if (te->getGlow() >= 1.f/255.f)
+				if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
 				{
-					emissive = true;
+					facep->clearVertexBuffer();
+					continue;
 				}
 
-				if (facep->isState(LLFace::TEXTURE_ANIM))
-				{
-					if (!vobj->mTexAnimMode)
-					{
-						facep->clearState(LLFace::TEXTURE_ANIM);
-					}
-				}
+				cur_total += facep->getGeomCount();
 
-				BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
-				U32 type = gPipeline.getPoolTypeFromTE(te, tex);
-				if (type != LLDrawPool::POOL_ALPHA && force_simple)
+				if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
 				{
-					type = LLDrawPool::POOL_SIMPLE;
-				}
-				facep->setPoolType(type);
+					const LLTextureEntry* te = facep->getTextureEntry();
+					LLViewerTexture* tex = facep->getTexture();
 
-				if (vobj->isHUDAttachment())
-				{
-					facep->setState(LLFace::FULLBRIGHT);
-				}
+					if (te->getGlow() >= 1.f/255.f)
+					{
+						emissive = true;
+					}
 
-				if (vobj->mTextureAnimp && vobj->mTexAnimMode)
-				{
-					if (vobj->mTextureAnimp->mFace <= -1)
+					if (facep->isState(LLFace::TEXTURE_ANIM))
 					{
-						S32 face;
-						for (face = 0; face < vobj->getNumTEs(); face++)
+						if (!vobj->mTexAnimMode)
 						{
-							drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM);
+							facep->clearState(LLFace::TEXTURE_ANIM);
 						}
 					}
-					else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+
+					BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
+					U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+					if (type != LLDrawPool::POOL_ALPHA && force_simple)
 					{
-						drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM);
+						type = LLDrawPool::POOL_SIMPLE;
 					}
-				}
+					facep->setPoolType(type);
 
-				if (type == LLDrawPool::POOL_ALPHA)
-				{
-					if (facep->canRenderAsMask())
-					{ //can be treated as alpha mask
-						simple_faces.push_back(facep);
-					}
-					else
+					if (vobj->isHUDAttachment())
 					{
-						if (te->getColor().mV[3] > 0.f)
-						{ //only treat as alpha in the pipeline if < 100% transparent
-							drawablep->setState(LLDrawable::HAS_ALPHA);
-						}
-						alpha_faces.push_back(facep);
+						facep->setState(LLFace::FULLBRIGHT);
 					}
-				}
-				else
-				{
-					if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+
+					if (vobj->mTextureAnimp && vobj->mTexAnimMode)
 					{
-						facep->mLastUpdateTime = gFrameTimeSeconds;
+						if (vobj->mTextureAnimp->mFace <= -1)
+						{
+							S32 face;
+							for (face = 0; face < vobj->getNumTEs(); face++)
+							{
+								LLFace * facep = drawablep->getFace(face);
+								if (facep)
+								{
+									facep->setState(LLFace::TEXTURE_ANIM);
+								}
+							}
+						}
+						else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+						{
+							LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace);
+							if (facep)
+							{
+								facep->setState(LLFace::TEXTURE_ANIM);
+							}
+						}
 					}
 
-					if (gPipeline.canUseWindLightShadersOnObjects()
-						&& LLPipeline::sRenderBump)
+					if (type == LLDrawPool::POOL_ALPHA)
 					{
-						if (te->getBumpmap())
-						{ //needs normal + binormal
-							bump_faces.push_back(facep);
-						}
-						else if (te->getShiny() || !te->getFullbright())
-						{ //needs normal
+						if (facep->canRenderAsMask())
+						{ //can be treated as alpha mask
 							simple_faces.push_back(facep);
 						}
-						else 
-						{ //doesn't need normal
-							facep->setState(LLFace::FULLBRIGHT);
-							fullbright_faces.push_back(facep);
+						else
+						{
+							if (te->getColor().mV[3] > 0.f)
+							{ //only treat as alpha in the pipeline if < 100% transparent
+								drawablep->setState(LLDrawable::HAS_ALPHA);
+							}
+							alpha_faces.push_back(facep);
 						}
 					}
 					else
 					{
-						if (te->getBumpmap() && LLPipeline::sRenderBump)
-						{ //needs normal + binormal
-							bump_faces.push_back(facep);
+						if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+						{
+							facep->mLastUpdateTime = gFrameTimeSeconds;
 						}
-						else if ((te->getShiny() && LLPipeline::sRenderBump) ||
-							!(te->getFullbright() || bake_sunlight))
-						{ //needs normal
-							simple_faces.push_back(facep);
+
+						if (gPipeline.canUseWindLightShadersOnObjects()
+							&& LLPipeline::sRenderBump)
+						{
+							if (te->getBumpmap())
+							{ //needs normal + binormal
+								bump_faces.push_back(facep);
+							}
+							else if (te->getShiny() || !te->getFullbright())
+							{ //needs normal
+								simple_faces.push_back(facep);
+							}
+							else 
+							{ //doesn't need normal
+								facep->setState(LLFace::FULLBRIGHT);
+								fullbright_faces.push_back(facep);
+							}
 						}
-						else 
-						{ //doesn't need normal
-							facep->setState(LLFace::FULLBRIGHT);
-							fullbright_faces.push_back(facep);
+						else
+						{
+							if (te->getBumpmap() && LLPipeline::sRenderBump)
+							{ //needs normal + binormal
+								bump_faces.push_back(facep);
+							}
+							else if ((te->getShiny() && LLPipeline::sRenderBump) ||
+								!(te->getFullbright() || bake_sunlight))
+							{ //needs normal
+								simple_faces.push_back(facep);
+							}
+							else 
+							{ //doesn't need normal
+								facep->setState(LLFace::FULLBRIGHT);
+								fullbright_faces.push_back(facep);
+							}
 						}
 					}
 				}
+				else
+				{	//face has no renderable geometry
+					facep->clearVertexBuffer();
+				}		
 			}
-			else
-			{	//face has no renderable geometry
-				facep->clearVertexBuffer();
-			}		
-		}
 
-		if (is_rigged)
-		{
-			drawablep->setState(LLDrawable::RIGGED);
-		}
-		else
-		{
-			drawablep->clearState(LLDrawable::RIGGED);
+			if (is_rigged)
+			{
+				drawablep->setState(LLDrawable::RIGGED);
+			}
+			else
+			{
+				drawablep->clearState(LLDrawable::RIGGED);
+			}
 		}
 	}
 
@@ -4564,15 +4663,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 	}
 }
 
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");
 
 void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 {
 	llassert(group);
 	if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
 	{
-		LLFastTimer tm(FTM_VOLUME_GEOM);
+		LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+		LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
+
 		S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
 
 		group->mBuilt = 1.f;
@@ -4581,14 +4680,18 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 
 		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
 		{
-			LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);
 			LLDrawable* drawablep = *drawable_iter;
 
-			if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
+			if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
 			{
 				LLVOVolume* vobj = drawablep->getVOVolume();
 				vobj->preRebuild();
 
+				if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+				{
+					vobj->updateRelativeXform(true);
+				}
+
 				LLVolume* volume = vobj->getVolume();
 				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
 				{
@@ -4598,6 +4701,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 						LLVertexBuffer* buff = face->getVertexBuffer();
 						if (buff)
 						{
+							llassert(!face->isState(LLFace::RIGGED));
 							face->getGeometryVolume(*volume, face->getTEOffset(), 
 								vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
 
@@ -4608,6 +4712,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 						}
 					}
 				}
+
+				if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+				{
+					vobj->updateRelativeXform();
+				}
+
 				
 				drawablep->clearState(LLDrawable::REBUILD_ALL);
 			}
@@ -4636,10 +4746,13 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
 				{
 					LLFace* face = drawablep->getFace(i);
-					LLVertexBuffer* buff = face->getVertexBuffer();
-					if (face && buff && buff->isLocked())
+					if (face)
 					{
-						buff->flush();
+						LLVertexBuffer* buff = face->getVertexBuffer();
+						if (buff && buff->isLocked())
+						{
+							buff->flush();
+						}
 					}
 				}
 			} 
@@ -4648,7 +4761,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 		group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
 	}
 
-	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
+//	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
 }
 
 struct CompareBatchBreakerModified
@@ -4674,8 +4787,20 @@ struct CompareBatchBreakerModified
 	}
 };
 
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
+
+
+
+
+
 void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
 {
+	LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+
 	U32 buffer_usage = group->mBufferUsage;
 	
 #if LL_DARWIN
@@ -4693,15 +4818,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
 	max_vertices = llmin(max_vertices, (U32) 65535);
 
-	if (!distance_sort)
-	{
-		//sort faces by things that break batches
-		std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
-	}
-	else
 	{
-		//sort faces by distance
-		std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+		LLFastTimer t(FTM_GEN_DRAW_INFO_SORT);
+		if (!distance_sort)
+		{
+			//sort faces by things that break batches
+			std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
+		}
+		else
+		{
+			//sort faces by distance
+			std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+		}
 	}
 				
 	bool hud_group = group->isHUDGroup() ;
@@ -4766,57 +4894,86 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 		
 		std::vector<LLViewerTexture*> texture_list;
 
-		if (batch_textures)
 		{
-			U8 cur_tex = 0;
-			facep->setTextureIndex(cur_tex);
-			texture_list.push_back(tex);
-
-			//if (can_batch_texture(facep))
+			LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
+			if (batch_textures)
 			{
-				while (i != faces.end())
+				U8 cur_tex = 0;
+				facep->setTextureIndex(cur_tex);
+				texture_list.push_back(tex);
+
+				//if (can_batch_texture(facep))
 				{
-					facep = *i;
-					if (facep->getTexture() != tex)
+					while (i != faces.end())
 					{
-						if (distance_sort)
-						{ //textures might be out of order, see if texture exists in current batch
-							bool found = false;
-							for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
-							{
-								if (facep->getTexture() == texture_list[tex_idx])
+						facep = *i;
+						if (facep->getTexture() != tex)
+						{
+							if (distance_sort)
+							{ //textures might be out of order, see if texture exists in current batch
+								bool found = false;
+								for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
 								{
-									cur_tex = tex_idx;
-									found = true;
-									break;
+									if (facep->getTexture() == texture_list[tex_idx])
+									{
+										cur_tex = tex_idx;
+										found = true;
+										break;
+									}
 								}
-							}
 
-							if (!found)
+								if (!found)
+								{
+									cur_tex = texture_list.size();
+								}
+							}
+							else
 							{
-								cur_tex = texture_list.size();
+								cur_tex++;
 							}
-						}
-						else
-						{
-							cur_tex++;
-						}
 
-						if (!can_batch_texture(facep))
-						{ //face is bump mapped or has an animated texture matrix -- can't 
-							//batch more than 1 texture at a time
-							break;
+							if (!can_batch_texture(facep))
+							{ //face is bump mapped or has an animated texture matrix -- can't 
+								//batch more than 1 texture at a time
+								break;
+							}
+
+							if (cur_tex >= texture_index_channels)
+							{ //cut batches when index channels are depleted
+								break;
+							}
+
+							tex = facep->getTexture();
+
+							texture_list.push_back(tex);
 						}
 
-						if (cur_tex >= texture_index_channels)
-						{ //cut batches when index channels are depleted
+						if (geom_count + facep->getGeomCount() > max_vertices)
+						{ //cut batches on geom count too big
 							break;
 						}
 
-						tex = facep->getTexture();
+						++i;
+						index_count += facep->getIndicesCount();
+						geom_count += facep->getGeomCount();
 
-						texture_list.push_back(tex);
+						facep->setTextureIndex(cur_tex);
 					}
+				}
+
+				tex = texture_list[0];
+			}
+			else
+			{
+				while (i != faces.end() && 
+					(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
+				{
+					facep = *i;
+			
+
+					//face has no texture index
+					facep->mDrawInfo = NULL;
+					facep->setTextureIndex(255);
 
 					if (geom_count + facep->getGeomCount() > max_vertices)
 					{ //cut batches on geom count too big
@@ -4826,69 +4983,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 					++i;
 					index_count += facep->getIndicesCount();
 					geom_count += facep->getGeomCount();
-
-					facep->setTextureIndex(cur_tex);
 				}
 			}
-
-			tex = texture_list[0];
 		}
-		else
-		{
-			while (i != faces.end() && 
-				(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
-			{
-				facep = *i;
-			
 
-				//face has no texture index
-				facep->mDrawInfo = NULL;
-				facep->setTextureIndex(255);
-
-				if (geom_count + facep->getGeomCount() > max_vertices)
-				{ //cut batches on geom count too big
-					break;
-				}
-
-				++i;
-				index_count += facep->getIndicesCount();
-				geom_count += facep->getGeomCount();
-			}
-		}
-	
-		//create/delete/resize vertex buffer if needed
+		//create vertex buffer
 		LLVertexBuffer* buffer = NULL;
 
-		{ //try to find a buffer to reuse
-			LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
-		
-			if (found_iter != group->mBufferMap[mask].end())
-			{
-				if ((U32) buffer_index < found_iter->second.size())
-				{
-					buffer = found_iter->second[buffer_index];
-				}
-			}
-		}
-						
-		if (!buffer || !buffer->isWriteable())
-		{ //create new buffer if needed
+		{
+			LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE);
 			buffer = createVertexBuffer(mask, buffer_usage);
 			buffer->allocateBuffer(geom_count, index_count, TRUE);
 		}
-		else 
-		{ //resize pre-existing buffer
-			if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage ||
-				buffer->getTypeMask() != mask)
-			{
-				buffer = createVertexBuffer(mask, buffer_usage);
-				buffer->allocateBuffer(geom_count, index_count, TRUE);
-			}
-			else
-			{
-				buffer->resizeBuffer(geom_count, index_count);
-			}
-		}
 
 		group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
 
@@ -4922,10 +5028,22 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
 					LLVOVolume* vobj = drawablep->getVOVolume();
 					LLVolume* volume = vobj->getVolume();
 
+					if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+					{
+						vobj->updateRelativeXform(true);
+					}
+
 					U32 te_idx = facep->getTEOffset();
 
+					llassert(!facep->isState(LLFace::RIGGED));
+
 					facep->getGeometryVolume(*volume, te_idx, 
-						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset);
+						vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true);
+
+					if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+					{
+						vobj->updateRelativeXform(false);
+					}
 				}
 			}
 
@@ -5089,6 +5207,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
 	mFaceList.clear();
 
 	//for each drawable
+
 	for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
 	{
 		LLDrawable* drawablep = *drawable_iter;
@@ -5109,17 +5228,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
 			//sum up face verts and indices
 			drawablep->updateFaceSize(i);
 			LLFace* facep = drawablep->getFace(i);
-			if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
+			if (facep)
 			{
-				vertex_count += facep->getGeomCount();
-				index_count += facep->getIndicesCount();
-				llassert(facep->getIndicesCount() < 65536);
-				//remember face (for sorting)
-				mFaceList.push_back(facep);
-			}
-			else
-			{
-				facep->clearVertexBuffer();
+				if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA && 
+					facep->getGeomCount() + vertex_count <= 65536)
+				{
+					vertex_count += facep->getGeomCount();
+					index_count += facep->getIndicesCount();
+				
+					//remember face (for sorting)
+					mFaceList.push_back(facep);
+				}
+				else
+				{
+					facep->clearVertexBuffer();
+				}
 			}
 		}
 	}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 3cf434dc260a917e7a1db1f7225a4ab86157331d..c4505b4bd8ece1f8b6db8012171b78413898c151 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -79,7 +79,7 @@ class LLVolumeInterface
 	virtual bool isVolumeGlobal() const = 0; // Are we in global space?
 	virtual bool isActive() const = 0; // Is this object currently active?
 	virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0;
-	virtual void updateRelativeXform() = 0;
+	virtual void updateRelativeXform(bool force_identity = false) = 0;
 	virtual U32 getID() const = 0;
 	virtual void preRebuild() = 0;
 };
@@ -203,7 +203,7 @@ class LLVOVolume : public LLViewerObject
 														  LLAssetType::EType type,
 														  void* user_data, S32 status, LLExtStat ext_status);
 					
-				void	updateRelativeXform();
+				void	updateRelativeXform(bool force_identity = false);
 	/*virtual*/ BOOL	updateGeometry(LLDrawable *drawable);
 	/*virtual*/ void	updateFaceSize(S32 idx);
 	/*virtual*/ BOOL	updateLOD();
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index cd7815794444869bfa417251a8605f30ef7276a4..942eff61718caab626837ba0c8b64fc5206bd575 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -146,6 +146,10 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
 		drawable->addFace(poolp, NULL);
 	}
 	face = drawable->getFace(0);
+	if (!face)
+	{
+		return TRUE;
+	}
 
 //	LLVector2 uvs[4];
 //	LLVector3 vtx[4];
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ed636a40b290ae73045d8fb8b981a05d8e6e5cf7..49c4f37871cbd2e362127d535f4aed6c49c43425 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -51,6 +51,10 @@
 // newview includes
 #include "llagent.h"
 #include "llagentcamera.h"
+#include "llappviewer.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
 #include "lldrawable.h"
 #include "lldrawpoolalpha.h"
 #include "lldrawpoolavatar.h"
@@ -264,6 +268,7 @@ std::string gPoolNames[] =
 void drawBox(const LLVector3& c, const LLVector3& r);
 void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
 U32 nhpo2(U32 v);
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
 
 glh::matrix4f glh_copy_matrix(F32* src)
 {
@@ -403,9 +408,11 @@ LLPipeline::LLPipeline() :
 	mInitialized(FALSE),
 	mVertexShadersEnabled(FALSE),
 	mVertexShadersLoaded(0),
+	mTransformFeedbackPrimitives(0),
 	mRenderDebugFeatureMask(0),
 	mRenderDebugMask(0),
 	mOldRenderDebugMask(0),
+	mMeshDirtyQueryObject(0),
 	mGroupQ1Locked(false),
 	mGroupQ2Locked(false),
 	mResetVertexBuffers(false),
@@ -504,6 +511,11 @@ void LLPipeline::init()
 		mSpotLightFade[i] = 1.f;
 	}
 
+	if (mCubeVB.isNull())
+	{
+		mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+	}
+
 	mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
 	mDeferredVB->allocateBuffer(8, 0, true);
 	setLightingDetail(-1);
@@ -693,6 +705,12 @@ void LLPipeline::destroyGL()
 	{
 		LLVertexBuffer::sEnableVBOs = FALSE;
 	}
+
+	if (mMeshDirtyQueryObject)
+	{
+		glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+		mMeshDirtyQueryObject = 0;
+	}
 }
 
 static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
@@ -942,6 +960,7 @@ void LLPipeline::refreshCachedSettings()
 
 	LLPipeline::sUseOcclusion = 
 			(!gUseWireframe
+			&& LLGLSLShader::sNoFixedFunction
 			&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") 
 			&& gSavedSettings.getBOOL("UseOcclusion") 
 			&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
@@ -1030,13 +1049,13 @@ void LLPipeline::releaseGLBuffers()
 	
 	if (mNoiseMap)
 	{
-		LLImageGL::deleteTextures(1, &mNoiseMap);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);
 		mNoiseMap = 0;
 	}
 
 	if (mTrueNoiseMap)
 	{
-		LLImageGL::deleteTextures(1, &mTrueNoiseMap);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);
 		mTrueNoiseMap = 0;
 	}
 
@@ -1060,7 +1079,7 @@ void LLPipeline::releaseLUTBuffers()
 {
 	if (mLightFunc)
 	{
-		LLImageGL::deleteTextures(1, &mLightFunc);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);
 		mLightFunc = 0;
 	}
 }
@@ -1138,7 +1157,7 @@ void LLPipeline::createGLBuffers()
 				noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
 			}
 
-			LLImageGL::generateTextures(1, &mNoiseMap);
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);
 			
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
@@ -1154,7 +1173,7 @@ void LLPipeline::createGLBuffers()
 				noise[i] = ll_frand()*2.0-1.0;
 			}
 
-			LLImageGL::generateTextures(1, &mTrueNoiseMap);
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
 			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
@@ -1210,7 +1229,7 @@ void LLPipeline::createLUTBuffers()
 				}
 			}
 			
-			LLImageGL::generateTextures(1, &mLightFunc);
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
 			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
@@ -1820,6 +1839,16 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
 		if (done)
 		{
 			drawablep->clearState(LLDrawable::ON_MOVE_LIST);
+			if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+			{ //will likely not receive any future world matrix updates
+				// -- this keeps attachments from getting stuck in space and falling off your avatar
+				drawablep->clearState(LLDrawable::ANIMATED_CHILD);
+				markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE);
+				if (drawablep->getVObj())
+				{
+					drawablep->getVObj()->dirtySpatialGroup(TRUE);
+				}
+			}
 			iter = moved_list.erase(curiter);
 		}
 	}
@@ -2214,8 +2243,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 	gGLLastMatrix = NULL;
 	gGL.loadMatrix(gGLLastModelView);
 
-
-	LLVertexBuffer::unbind();
 	LLGLDisable blend(GL_BLEND);
 	LLGLDisable test(GL_ALPHA_TEST);
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -2259,7 +2286,16 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 	{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can
 		// (shadow render uses a special shader that clamps to clip planes)
 		bound_shader = true;
-		gOcclusionProgram.bind();
+		gOcclusionCubeProgram.bind();
+	}
+
+	if (sUseOcclusion > 1)
+	{
+		if (mCubeVB.isNull())
+		{ //cube VB will be used for issuing occlusion queries
+			mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+		}
+		mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 	}
 	
 	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
@@ -2291,7 +2327,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 
 	if (bound_shader)
 	{
-		gOcclusionProgram.unbind();
+		gOcclusionCubeProgram.unbind();
 	}
 
 	camera.disableUserClipPlane();
@@ -2424,14 +2460,20 @@ void LLPipeline::doOcclusion(LLCamera& camera)
 		{
 			if (LLPipeline::sShadowRender)
 			{
-				gDeferredShadowProgram.bind();
+				gDeferredShadowCubeProgram.bind();
 			}
 			else
 			{
-				gOcclusionProgram.bind();
+				gOcclusionCubeProgram.bind();
 			}
 		}
 
+		if (mCubeVB.isNull())
+		{ //cube VB will be used for issuing occlusion queries
+			mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+		}
+		mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
 		for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
 		{
 			LLSpatialGroup* group = *iter;
@@ -2443,11 +2485,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)
 		{
 			if (LLPipeline::sShadowRender)
 			{
-				gDeferredShadowProgram.unbind();
+				gDeferredShadowCubeProgram.unbind();
 			}
 			else
 			{
-				gOcclusionProgram.unbind();
+				gOcclusionCubeProgram.unbind();
 			}
 		}
 
@@ -2466,6 +2508,8 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
 	return update_complete;
 }
 
+static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool");
+
 void LLPipeline::updateGL()
 {
 	while (!LLGLUpdate::sGLQ.empty())
@@ -2475,6 +2519,11 @@ void LLPipeline::updateGL()
 		glu->mInQ = FALSE;
 		LLGLUpdate::sGLQ.pop_front();
 	}
+
+	{ //seed VBO Pools
+		LLFastTimer t(FTM_SEED_VBO_POOLS);
+		LLVertexBuffer::seedPools();
+	}
 }
 
 void LLPipeline::rebuildPriorityGroups()
@@ -2838,6 +2887,11 @@ void LLPipeline::processPartitionQ()
 	mPartitionQ.clear();
 }
 
+void LLPipeline::markMeshDirty(LLSpatialGroup* group)
+{
+	mMeshDirtyGroup.push_back(group);
+}
+
 void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
 {
 	LLMemType mt(LLMemType::MTYPE_PIPELINE);
@@ -3189,7 +3243,11 @@ void renderScriptedBeacons(LLDrawable* drawablep)
 			S32 count = drawablep->getNumFaces();
 			for (face_id = 0; face_id < count; face_id++)
 			{
-				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+				LLFace * facep = drawablep->getFace(face_id);
+				if (facep) 
+				{
+					gPipeline.mHighlightFaces.push_back(facep);
+				}
 			}
 		}
 	}
@@ -3215,7 +3273,11 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep)
 			S32 count = drawablep->getNumFaces();
 			for (face_id = 0; face_id < count; face_id++)
 			{
-				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+				LLFace * facep = drawablep->getFace(face_id);
+				if (facep)
+				{
+					gPipeline.mHighlightFaces.push_back(facep);
+				}
 			}
 		}
 	}
@@ -3240,7 +3302,11 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
 			S32 count = drawablep->getNumFaces();
 			for (face_id = 0; face_id < count; face_id++)
 			{
-				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+				LLFace * facep = drawablep->getFace(face_id);
+				if (facep)
+				{
+					gPipeline.mHighlightFaces.push_back(facep);
+				}
 			}
 		}
 	}
@@ -3276,7 +3342,11 @@ void renderMOAPBeacons(LLDrawable* drawablep)
 			S32 count = drawablep->getNumFaces();
 			for (face_id = 0; face_id < count; face_id++)
 			{
-				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+				LLFace * facep = drawablep->getFace(face_id);
+				if (facep)
+				{
+					gPipeline.mHighlightFaces.push_back(facep);
+				}
 			}
 		}
 	}
@@ -3301,7 +3371,11 @@ void renderParticleBeacons(LLDrawable* drawablep)
 			S32 count = drawablep->getNumFaces();
 			for (face_id = 0; face_id < count; face_id++)
 			{
-				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+				LLFace * facep = drawablep->getFace(face_id);
+				if (facep)
+				{
+					gPipeline.mHighlightFaces.push_back(facep);
+				}
 			}
 		}
 	}
@@ -3319,7 +3393,11 @@ void renderSoundHighlights(LLDrawable* drawablep)
 			S32 count = drawablep->getNumFaces();
 			for (face_id = 0; face_id < count; face_id++)
 			{
-				gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+				LLFace * facep = drawablep->getFace(face_id);
+				if (facep)
+				{
+					gPipeline.mHighlightFaces.push_back(facep);
+				}
 			}
 		}
 	}
@@ -3350,21 +3428,7 @@ void LLPipeline::postSort(LLCamera& camera)
 	rebuildPriorityGroups();
 	llpushcallstacks ;
 
-	const S32 bin_count = 1024*8;
-		
-	static LLCullResult::drawinfo_list_t alpha_bins[bin_count];
-	static U32 bin_size[bin_count];
-
-	//clear one bin per frame to avoid memory bloat
-	static S32 clear_idx = 0;
-	clear_idx = (1+clear_idx)%bin_count;
-	alpha_bins[clear_idx].clear();
-
-	for (U32 j = 0; j < bin_count; j++)
-	{
-		bin_size[j] = 0;
-	}
-
+	
 	//build render map
 	for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
 	{
@@ -3436,11 +3500,43 @@ void LLPipeline::postSort(LLCamera& camera)
 			}
 		}
 	}
+	
+	//flush particle VB
+	LLVOPartGroup::sVB->flush();
+
+	/*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty();
+
+	if (use_transform_feedback)
+	{ //place a query around potential transform feedback code for synchronization
+		mTransformFeedbackPrimitives = 0;
+
+		if (!mMeshDirtyQueryObject)
+		{
+			glGenQueriesARB(1, &mMeshDirtyQueryObject);
+		}
+
 		
+		glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
+	}*/
+
+	//pack vertex buffers for groups that chose to delay their updates
+	for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
+	{
+		(*iter)->rebuildMesh();
+	}
+
+	/*if (use_transform_feedback)
+	{
+		glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+	}*/
+	
+	mMeshDirtyGroup.clear();
+
 	if (!sShadowRender)
 	{
 		std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
 	}
+
 	llpushcallstacks ;
 	// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
 	if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
@@ -3514,7 +3610,11 @@ void LLPipeline::postSort(LLCamera& camera)
 				{
 					if (object->mDrawable)
 					{
-						gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te));
+						LLFace * facep = object->mDrawable->getFace(te);
+						if (facep)
+						{
+							gPipeline.mSelectedFaces.push_back(facep);
+						}
 					}
 					return true;
 				}
@@ -3523,6 +3623,33 @@ void LLPipeline::postSort(LLCamera& camera)
 		}
 	}
 
+	/*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence");
+	static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work");
+	if (use_transform_feedback)
+	{ //using transform feedback, wait for transform feedback to complete
+		LLFastTimer t(FTM_TRANSFORM_WAIT);
+
+		S32 done = 0;
+		//glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count);
+		
+		glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
+		
+		while (!done)
+		{ 
+			{
+				LLFastTimer t(FTM_TRANSFORM_DO_WORK);
+				F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+				//do some useful work while we wait
+				LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+				LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+				LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+			}
+			glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
+		}
+
+		mTransformFeedbackPrimitives = 0;
+	}*/
+						
 	//LLSpatialGroup::sNoDelete = FALSE;
 	llpushcallstacks ;
 }
@@ -6219,7 +6346,10 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
 	for (S32 i = 0; i < drawable->getNumFaces(); i++)
 	{
 		LLFace* facep = drawable->getFace(i);
-		facep->clearVertexBuffer();
+		if (facep)
+		{
+			facep->clearVertexBuffer();
+		}
 	}
 }
 
@@ -6237,6 +6367,8 @@ void LLPipeline::doResetVertexBuffers()
 	
 	mResetVertexBuffers = false;
 
+	mCubeVB = NULL;
+
 	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
 			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
 	{
@@ -6255,11 +6387,15 @@ void LLPipeline::doResetVertexBuffers()
 
 	gSky.resetVertexBuffers();
 
+	LLVOPartGroup::destroyGL();
+
 	LLVertexBuffer::cleanupClass();
 	
 	//delete all name pool caches
 	LLGLNamePool::cleanupPools();
 
+	
+
 	if (LLVertexBuffer::sGLCount > 0)
 	{
 		llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl;
@@ -6279,6 +6415,8 @@ void LLPipeline::doResetVertexBuffers()
 	LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
 
 	LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+
+	LLVOPartGroup::restoreGL();
 }
 
 void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
@@ -7466,12 +7604,17 @@ void LLPipeline::renderDeferredLighting()
 			std::list<LLVector4> light_colors;
 
 			LLVertexBuffer::unbind();
-			LLVector4a* v = (LLVector4a*) vert.get();
 
 			{
 				bindDeferredShader(gDeferredLightProgram);
-				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+				
+				if (mCubeVB.isNull())
+				{
+					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+				}
 
+				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+				
 				LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
 				{
@@ -7517,25 +7660,7 @@ void LLPipeline::renderDeferredLighting()
 					}
 
 					sVisibleLightCount++;
-
-					glh::vec3f tc(c);
-					mat.mult_matrix_vec(tc);
-					
-					//vertex positions are encoded so the 3 bits of their vertex index 
-					//correspond to their axis facing, with bit position 3,2,1 matching
-					//axis facing x,y,z, bit set meaning positive facing, bit clear 
-					//meaning negative facing
-					mDeferredVB->getVertexStrider(vert);
-					v[0].set(c[0]-s,c[1]-s,c[2]-s);  // 0 - 0000 
-					v[1].set(c[0]-s,c[1]-s,c[2]+s);  // 1 - 0001
-					v[2].set(c[0]-s,c[1]+s,c[2]-s);  // 2 - 0010
-					v[3].set(c[0]-s,c[1]+s,c[2]+s);  // 3 - 0011
-																									   
-					v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
-					v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
-					v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
-					v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
-
+										
 					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
 						camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
 						camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
@@ -7553,16 +7678,13 @@ void LLPipeline::renderDeferredLighting()
 							}
 							
 							LLFastTimer ftm(FTM_LOCAL_LIGHTS);
-							//glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
-							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
 							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
 							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
 							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
-							//gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
 							gGL.syncMatrices();
-							mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-							glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
-								GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
+							
+							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
 							stop_glerror();
 						}
 					}
@@ -7575,6 +7697,9 @@ void LLPipeline::renderDeferredLighting()
 							continue;
 						}
 
+						glh::vec3f tc(c);
+						mat.mult_matrix_vec(tc);
+					
 						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
 						light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
 					}
@@ -7587,7 +7712,7 @@ void LLPipeline::renderDeferredLighting()
 				LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 				bindDeferredShader(gDeferredSpotLightProgram);
 
-				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
 				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 
@@ -7605,36 +7730,17 @@ void LLPipeline::renderDeferredLighting()
 
 					sVisibleLightCount++;
 
-					glh::vec3f tc(c);
-					mat.mult_matrix_vec(tc);
-					
 					setupSpotLight(gDeferredSpotLightProgram, drawablep);
 					
 					LLColor3 col = volume->getLightColor();
 					
-					//vertex positions are encoded so the 3 bits of their vertex index 
-					//correspond to their axis facing, with bit position 3,2,1 matching
-					//axis facing x,y,z, bit set meaning positive facing, bit clear 
-					//meaning negative facing
-					mDeferredVB->getVertexStrider(vert);
-					v[0].set(c[0]-s,c[1]-s,c[2]-s);  // 0 - 0000 
-					v[1].set(c[0]-s,c[1]-s,c[2]+s);  // 1 - 0001
-					v[2].set(c[0]-s,c[1]+s,c[2]-s);  // 2 - 0010
-					v[3].set(c[0]-s,c[1]+s,c[2]+s);  // 3 - 0011
-																									   
-					v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
-					v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
-					v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
-					v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
-					
-					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
 					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
 					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
 					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
 					gGL.syncMatrices();
-					mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-					glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
-							GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
+										
+					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
 				}
 				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
 				unbindDeferredShader(gDeferredSpotLightProgram);
@@ -7666,8 +7772,6 @@ void LLPipeline::renderDeferredLighting()
 				LLVector4 light[max_count];
 				LLVector4 col[max_count];
 
-//				glVertexPointer(2, GL_FLOAT, 0, vert);
-
 				F32 far_z = 0.f;
 
 				while (!fullscreen_lights.empty())
@@ -8324,7 +8428,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 
 	if (use_shader)
 	{
-		gDeferredShadowProgram.bind();
+		gDeferredShadowCubeProgram.bind();
 	}
 
 	updateCull(shadow_cam, result);
@@ -8341,17 +8445,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 	stop_glerror();
 	gGLLastMatrix = NULL;
 
-	{
-		//LLGLDepthTest depth(GL_TRUE);
-		//glClear(GL_DEPTH_BUFFER_BIT);
-	}
-
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
 	stop_glerror();
 	
-	//glCullFace(GL_FRONT);
-
 	LLVertexBuffer::unbind();
 
 	{
@@ -8359,6 +8456,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 		{ //occlusion program is general purpose depth-only no-textures
 			gOcclusionProgram.bind();
 		}
+		else
+		{
+			gDeferredShadowProgram.bind();
+		}
 
 		gGL.diffuseColor4f(1,1,1,1);
 		gGL.setColorMask(false, false);
@@ -8408,7 +8509,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
 
 	//glCullFace(GL_BACK);
 
-	gDeferredShadowProgram.bind();
+	gDeferredShadowCubeProgram.bind();
 	gGLLastMatrix = NULL;
 	gGL.loadMatrix(gGLModelView);
 	doOcclusion(shadow_cam);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 5c623fc9f2dce8a634333893851be7ae6bf18db6..6ae482fa06c330ed3d064127d67a4af8bef912ec 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -163,6 +163,7 @@ class LLPipeline
 	void		markRebuild(LLSpatialGroup* group, BOOL priority = FALSE);
 	void        markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE);
 	void		markPartitionMove(LLDrawable* drawablep);
+	void		markMeshDirty(LLSpatialGroup* group);
 
 	//get the object between start and end that's closest to start.
 	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
@@ -544,6 +545,9 @@ class LLPipeline
 	//utility buffer for rendering post effects, gets abused by renderDeferredLighting
 	LLPointer<LLVertexBuffer> mDeferredVB;
 
+	//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
+	LLPointer<LLVertexBuffer> mCubeVB;
+
 	//sun shadow map
 	LLRenderTarget			mShadow[6];
 	std::vector<LLVector3>	mShadowFrustPoints[4];
@@ -595,6 +599,7 @@ class LLPipeline
 	BOOL					mVertexShadersEnabled;
 	S32						mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed
 
+	U32						mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback
 protected:
 	BOOL					mRenderTypeEnabled[NUM_RENDER_TYPES];
 	std::stack<std::string> mRenderTypeEnableStack;
@@ -652,6 +657,9 @@ class LLPipeline
 	LLSpatialGroup::sg_vector_t		mGroupQ1; //priority
 	LLSpatialGroup::sg_vector_t		mGroupQ2; // non-priority
 
+	LLSpatialGroup::sg_vector_t		mMeshDirtyGroup; //groups that need rebuildMesh called
+	U32 mMeshDirtyQueryObject;
+
 	LLDrawable::drawable_list_t		mPartitionQ; //drawables that need to update their spatial partition radius 
 
 	bool mGroupQ2Locked;
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index eabcc68916b11c30954c2e92d4c911f31dc09abf..7ca6820318ba3c96857760a0a14b320455163da3 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -54,6 +54,8 @@ with the same filename but different name
 
   <texture name="Arrow_Down" file_name="widgets/Arrow_Down.png"	preload="true" />
   <texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" />
+  <texture name="Arrow_Left" file_name="widgets/Arrow_Left.png" preload="true" />
+  <texture name="Arrow_Right" file_name="widgets/Arrow_Right.png" preload="true" />
 
   <texture name="AudioMute_Off" file_name="icons/AudioMute_Off.png" preload="false" />
   <texture name="AudioMute_Over" file_name="icons/AudioMute_Over.png" preload="false" />
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Left.png b/indra/newview/skins/default/textures/widgets/Arrow_Left.png
new file mode 100644
index 0000000000000000000000000000000000000000..a424282839c8d9c71d3785ae2ba4badccf0455db
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Arrow_Left.png differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Right.png b/indra/newview/skins/default/textures/widgets/Arrow_Right.png
new file mode 100644
index 0000000000000000000000000000000000000000..e32bee8f344c989aad93c36bab229a2d5f03e3c6
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/Arrow_Right.png differ
diff --git a/indra/newview/skins/default/xui/da/floater_model_wizard.xml b/indra/newview/skins/default/xui/da/floater_model_wizard.xml
deleted file mode 100644
index 8ad443581ac6fec32458a258a377392cb3026118..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/da/floater_model_wizard.xml
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="UPLOAD MODEL WIZARD">
-	<button label="5. Upload" name="upload_btn"/>
-	<button label="4. Review" name="review_btn"/>
-	<button label="3. Physics" name="physics2_btn"/>
-	<button label="3. Physics" name="physics_btn"/>
-	<button label="2. Optimize" name="optimize_btn"/>
-	<button label="1. Choose File" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="header_panel">
-			<text name="header_text">
-				Upload Model
-			</text>
-		</panel>
-		<text name="description">
-			This wizard will help you import mesh models to Second Life.  First specify a file containing the model you wish to import.  Second Life supports COLLADA (.dae) files.
-		</text>
-		<panel name="content">
-			<text name="Cache location">
-				Filename:
-			</text>
-			<button label="Browse..." label_selected="Browse..." name="browse"/>
-			<text name="dimensions">
-				X:         Y:         Z:
-			</text>
-			<text name="dimension_dividers">
-				|               |
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="header_panel">
-			<text name="header_text">
-				Optimize
-			</text>
-		</panel>
-		<text name="description">
-			This wizard has optimized your model to improve performance. You may adjust the results of the optimization process bellow or click Next to continue.
-		</text>
-		<panel name="content">
-			<text name="high_detail_text">
-				Generate Level of Detail: High
-			</text>
-			<text name="medium_detail_text">
-				Generate Level of Detail: Medium
-			</text>
-			<text name="low_detail_text">
-				Generate Level of Detail: Low
-			</text>
-			<text name="lowest_detail_text">
-				Generate Level of Detail: Lowest
-			</text>
-		</panel>
-		<panel name="content2">
-			<text name="lod_label">
-				Model Preview:
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="LOD to view in preview render">
-				<combo_item name="high">
-					High
-				</combo_item>
-				<combo_item name="medium">
-					Medium
-				</combo_item>
-				<combo_item name="low">
-					Low
-				</combo_item>
-				<combo_item name="lowest">
-					Lowest
-				</combo_item>
-			</combo_box>
-			<text name="streaming cost">
-				Resource Cost:    [COST]
-			</text>
-			<text name="dimensions">
-				X:         Y:         Z:
-			</text>
-			<text name="dimension_dividers">
-				|               |
-			</text>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="header_panel">
-			<text name="header_text">
-				Physics
-			</text>
-		</panel>
-		<text name="description">
-			The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used:
-		</text>
-		<panel name="content">
-			<text name="streaming cost">
-				Resource Cost:       [COST]
-			</text>
-		</panel>
-	</panel>
-	<panel name="physics2_panel">
-		<panel name="header_panel">
-			<text name="header_text">
-				Physics
-			</text>
-		</panel>
-		<text name="description">
-			Preview the physics shape below then click Next to continue.  To modify the physics shape, click the Back button.
-		</text>
-		<panel name="content">
-			<text name="lod_label">
-				Model Preview:
-			</text>
-			<combo_box name="preview_lod_combo3" tool_tip="LOD to view in preview render">
-				<combo_item name="high">
-					High
-				</combo_item>
-				<combo_item name="medium">
-					Medium
-				</combo_item>
-				<combo_item name="low">
-					Low
-				</combo_item>
-				<combo_item name="lowest">
-					Lowest
-				</combo_item>
-			</combo_box>
-			<text name="dimensions">
-				X:         Y:         Z:
-			</text>
-			<text name="dimension_dividers">
-				|               |
-			</text>
-			<text name="streaming cost">
-				Resource Cost:       [COST]
-			</text>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="header_panel">
-			<text name="header_text">
-				Review
-			</text>
-		</panel>
-		<text name="description">
-			Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload.
-		</text>
-		<panel name="content">
-			<text name="lod_label">
-				Model Preview:
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="LOD to view in preview render">
-				<combo_item name="high">
-					High
-				</combo_item>
-				<combo_item name="medium">
-					Medium
-				</combo_item>
-				<combo_item name="low">
-					Low
-				</combo_item>
-				<combo_item name="lowest">
-					Lowest
-				</combo_item>
-			</combo_box>
-			<text name="dimensions">
-				X:         Y:         Z:
-			</text>
-			<text name="dimension_dividers">
-				|               |
-			</text>
-		</panel>
-		<text name="streaming cost">
-			Resource Cost:         [COST]
-		</text>
-		<text name="physics cost">
-			Physics Cost:        [COST]
-		</text>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="header_panel">
-			<text name="header_text">
-				Upload Complete!
-			</text>
-		</panel>
-		<text name="description">
-			Congratulations! Your model has been sucessfully uploaded.  You will find the model in the Objects folder in your inventory.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Back" name="back"/>
-	<button label="Next &gt;&gt;" name="next"/>
-	<button label="Upload" name="upload" tool_tip="Upload to simulator"/>
-	<button label="Cancel" name="cancel"/>
-	<button label="Close" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		Idle
-	</string>
-	<string name="status_reading_file">
-		Loading...
-	</string>
-	<string name="status_generating_meshes">
-		Generating Meshes...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Error: Vertex number is more than 65534, aborted!
-	</string>
-	<string name="high">
-		High
-	</string>
-	<string name="medium">
-		Medium
-	</string>
-	<string name="low">
-		Low
-	</string>
-	<string name="lowest">
-		Lowest
-	</string>
-	<string name="mesh_status_good">
-		Ship it!
-	</string>
-	<string name="mesh_status_na">
-		N/A
-	</string>
-	<string name="mesh_status_none">
-		None
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Levels of detail have a different number of textureable faces.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Levels of detail have a different number of mesh instances.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		Level of detail has too many vertices.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Missing required level of detail.
-	</string>
-	<string name="layer_all">
-		All
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_model_wizard.xml b/indra/newview/skins/default/xui/de/floater_model_wizard.xml
deleted file mode 100644
index ee26d51d32e288308ef9e93b4f4e9f2b2c48c1b3..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/de/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="ASSISTENT ZUM HOCHLADEN VON MODELLEN">
-	<button label="5. Hochladen" name="upload_btn"/>
-	<button label="4. Überprüfen" name="review_btn"/>
-	<button label="3. Physik" name="physics_btn"/>
-	<button label="2. Optimieren" name="optimize_btn"/>
-	<button label="1. Datei auswählen" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Modelldatei auswählen
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Fortgeschrittene Benutzer: Wenn Sie bereits mit Tools zur Erstellung von 3D-Inhalten vertraut sind, können Sie den erweiterten Uploader verwenden.
-			</text>
-			<button label="Auf Erweitert wechseln" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Hochzuladende Modelldatei auswählen
-			</text>
-			<button label="Durchsuchen..." label_selected="Durchsuchen..." name="browse"/>
-			<text name="Model types">
-				Second Life unterstützt COLLADA-Dateien (.dae).
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				ACHTUNG:
-			</text>
-			<text name="warning_text">
-				Sie können den letzten Schritt nicht abschließen (Modell auf Second Life-Server hochladen). [secondlife:///app/floater/learn_more Weitere Infos], wie Sie Ihr Konto zum Hochladen von Netzmodellen einrichten.
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Modell optimieren
-			</text>
-		</panel>
-		<text name="optimize_description">
-			Wir haben das Modell auf Leistung optimiert. Sie können es bei Bedarf weiter anpassen.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Detailstufe generieren: hoch
-			</text>
-			<text name="medium_detail_text">
-				Detailstufe generieren: mittel
-			</text>
-			<text name="low_detail_text">
-				Detailstufe generieren: niedrig
-			</text>
-			<text name="lowest_detail_text">
-				Detailstufe generieren: niedrigste
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Geometrie neu berechnen" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Geometrievorschau
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung">
-				<combo_item name="high">
-					Viel Details
-				</combo_item>
-				<combo_item name="medium">
-					Mittlere Details
-				</combo_item>
-				<combo_item name="low">
-					Wenig Details
-				</combo_item>
-				<combo_item name="lowest">
-					Wenigste Details
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Physik anpassen
-			</text>
-		</panel>
-		<text name="physics_description">
-			Wir erstellen eine Form für die Außenhülle des Modells. Passen Sie die Detailstufe der Form wie für den beabsichtigten Zweck erforderlich an.
-		</text>
-		<panel name="physics_content">
-			<button label="Physik neu berechnen" name="recalculate_physics_btn"/>
-			<button label="Neu berechnen..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Physikvorschau
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung">
-				<combo_item name="high">
-					Viel Details
-				</combo_item>
-				<combo_item name="medium">
-					Mittlere Details
-				</combo_item>
-				<combo_item name="low">
-					Wenig Details
-				</combo_item>
-				<combo_item name="lowest">
-					Wenigste Details
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Überprüfen
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Auswirkung auf Parzelle/Region: Prim-Äquivalenzwert [EQUIV]
-			</text>
-			<text name="review_fee">
-				Die für das Hochladen anfallende Gebühr in Höhe von L$ [FEE] wird von Ihrem Konto abgebucht.
-			</text>
-			<text name="review_confirmation">
-				Durch Klicken auf „Hochladen“ bestätigen Sie, dass Sie die erforderlichen Rechte für das im Modell enthaltene Material besitzen.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Upload abgeschlossen
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Ihr Modell wurde hochgeladen.
-		</text>
-		<text name="inventory_text">
-			Sie finden das Modell im Objektordner Ihres Inventars.
-		</text>
-		<text name="charged_fee">
-			Von Ihrem Konto wurden [FEE] L$ abgebucht.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Zurück" name="back"/>
-	<button label="Weiter &gt;&gt;" name="next"/>
-	<button label="Gewichte und Gebühr berechnen &gt;&gt;" name="calculate"/>
-	<button label="Berechnen..." name="calculating"/>
-	<button label="Hochladen" name="upload" tool_tip="An Simulator hochladen"/>
-	<button label="Abbrechen" name="cancel"/>
-	<button label="Schließen" name="close"/>
-	<spinner name="import_scale" value="1,0"/>
-	<string name="status_idle">
-		Inaktiv
-	</string>
-	<string name="status_parse_error">
-		DAE-Parsing-Fehler. Details siehe Protokoll.
-	</string>
-	<string name="status_reading_file">
-		Laden...
-	</string>
-	<string name="status_generating_meshes">
-		Netze werden generiert...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Fehler: Anzahl von Vertices überschreitet 65534. Operation abgebrochen.
-	</string>
-	<string name="bad_element">
-		Fehler: ungültiges Element.
-	</string>
-	<string name="high">
-		Hoch
-	</string>
-	<string name="medium">
-		Mittel
-	</string>
-	<string name="low">
-		Niedrig
-	</string>
-	<string name="lowest">
-		Niedrigste
-	</string>
-	<string name="mesh_status_good">
-		Ausliefern
-	</string>
-	<string name="mesh_status_na">
-		--
-	</string>
-	<string name="mesh_status_none">
-		Keine
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Detailstufen haben unterschiedliche Anzahl texturfähiger Flächen.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Detailstufen haben unterschiedliche Anzahl von Netzinstanzen.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		Detailstufe hat zu viele Vertices.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Erforderliche Detailstufe fehlt.
-	</string>
-	<string name="layer_all">
-		Alle
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 060d88900327b5adf81538625697af44b2c9d353..63eb87f27a17531b618229d8883eaeb11119c0c1 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -196,27 +196,26 @@ Dummy Name replaced at run time
        top="5"
        width="435"
        word_wrap="true">
-        3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-        APR Copyright (C) 2000-2004 The Apache Software Foundation
-        Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-        cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+        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, The FreeType Project (www.freetype.org).
+        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) 2001, Xiphophorus
-        OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-        PCRE Copyright (c) 1997-2008 University of Cambridge
+        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-2002 Jean-loup Gailly and Mark Adler.
-        google-perftools Copyright (c) 2005, Google 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.
 
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index fb123ec4d1df418d7077b74183834f804d6107b4..793a6e6fa1ef6687508c6b3311fa7745af5a5392 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1354,79 +1354,13 @@ Only large parcels can be listed in search.
              top="150"
              width="430" />
             <combo_box
-             enabled="false"
-             height="23"
-             layout="topleft"
-             left="20"
-             top="194"
-             name="land category with adult"
-             visible="false"
-             width="140">
-                <combo_box.item
-                 label="Any Category"
-                 name="item0"
-                 value="any" />
-                <combo_box.item
-                 label="Linden Location"
-                 name="item1"
-                 value="linden" />
-                <combo_box.item
-                 label="Adult"
-                 name="item2"
-                 value="adult" />
-                <combo_box.item
-                 label="Arts &amp; Culture"
-                 name="item3"
-                 value="arts" />
-                <combo_box.item
-                 label="Business"
-                 name="item4"
-                 value="store" />
-                <combo_box.item
-                 label="Educational"
-                 name="item5"
-                 value="educational" />
-                <combo_box.item
-                 label="Gaming"
-                 name="item6"
-                 value="game" />
-                <combo_box.item
-                 label="Hangout"
-                 name="item7"
-                 value="gather" />
-                <combo_box.item
-                 label="Newcomer Friendly"
-                 name="item8"
-                 value="newcomer" />
-                <combo_box.item
-                 label="Parks &amp; Nature"
-                 name="item9"
-                 value="park" />
-                <combo_box.item
-                 label="Residential"
-                 name="item10"
-                 value="home" />
-                <combo_box.item
-                 label="Shopping"
-                 name="item11"
-                 value="shopping" />
-                <combo_box.item
-                 label="Rental"
-                 name="item13"
-                 value="rental" />
-                <combo_box.item
-                 label="Other"
-                 name="item12"
-                 value="other" />
-            </combo_box>
-            <combo_box
-             enabled="false"
+             enabled="true"
              height="23"
              layout="topleft"
              left="20"
              top="194"
              name="land category"
-             visible="false"
+             visible="true"
              width="140">
                 <combo_box.item
                  label="Any Category"
@@ -1989,11 +1923,11 @@ Only large parcels can be listed in search.
             <check_box
              follows="top|left"
              height="16"
-             label="Have been age-verified [ESTATE_AGE_LIMIT]"
+             label="Are age 18 or older [ESTATE_AGE_LIMIT]"
              layout="topleft"
              left_delta="0"
              name="limit_age_verified"
-             tool_tip="Residents must be age verified to access this parcel. See the [SUPPORT_SITE] for more information."
+             tool_tip="Residents must be age 18 or older to access this parcel. See the [SUPPORT_SITE] for more information."
              top_pad="4"
              width="278" />
             <check_box
diff --git a/indra/newview/skins/default/xui/en/floater_autoreplace.xml b/indra/newview/skins/default/xui/en/floater_autoreplace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0bfefc8abe36e9a9723b940c90cb3a6b6e6cb8cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_autoreplace.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ can_resize="false"
+ help_topic="autoreplace_settings"
+ save_rect="true"
+ height="455"
+ width="490"
+ name="autoreplace_floater"
+ title="Auto-Replace Settings">
+  <check_box
+   bottom_delta="30"
+   left_delta="15"
+   height="16"
+   width="100"
+   follows="left|top"
+   label="Enable Auto-Replace"
+   name="autoreplace_enable"
+   tool_tip="As you enter chat text, replace any of the keywords entered with the corresponding replacement"/>
+  <view_border
+   top_pad="15"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor1"/>
+  <button
+   top_pad="10"
+   left="10"
+   height="22"
+   width="110"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_import_list"
+   label="Import List..."
+   tool_tip="Load a previously exported list from a file."/>
+  <button
+   top_delta="0"
+   left_pad="10"
+   height="22"
+   width="110"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_export_list"
+   label="Export List..."
+   tool_tip="Save the selected list to a file so you can share it."/>
+  <button
+   top_delta="0"
+   left_pad="10"
+   height="22"
+   width="110"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_new_list"
+   label="New List..."
+   tool_tip="Create a new list."/>
+  <button
+   top_delta="0"
+   left_pad="10"
+   height="22"
+   width="110"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_delete_list"
+   label="Delete List"
+   tool_tip="Delete the selected list."/>
+  <scroll_list
+   top_pad="10"
+   left="10"
+   height="100"
+   width="370"
+   follows="left|top"
+   column_padding="0"
+   draw_heading="false"
+   multi_select="false"
+   name="autoreplace_list_name"
+   search_column="0">
+  </scroll_list>
+  <button
+   top_delta="23"
+   left_pad="10"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_list_up"
+   image_overlay="Arrow_Up"
+   tool_tip="Move this list up in priority."/>
+  <button
+   top_pad="10"
+   left_delta="0"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_list_down"
+   image_overlay="Arrow_Down"
+   tool_tip="Move this list down in priority."/>
+  <view_border
+   top_pad="36"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor2"/>
+  <scroll_list
+   top_pad="10"
+   left="10"
+   height="120"
+   width="370"
+   follows="left|top"
+   column_padding="0"
+   draw_heading="true"
+   multi_select="true"
+   name="autoreplace_list_replacements"
+   search_column="0">
+    <scroll_list.columns
+        label="Keyword"
+        name="keyword"
+        relative_width="0.30" />
+    <scroll_list.columns
+        label="Replacement"
+        name="replacement"
+        relative_width="0.70" />
+  </scroll_list>
+  <button
+   top_delta="41"
+   left_pad="10"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_add_entry"
+   label="Add..."/>
+  <button 
+   top_pad="10"
+   left_delta="0"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_delete_entry"
+   label="Remove"/>
+  <view_border
+   top_pad="38"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor3"/>
+  <text
+   type="string"
+   follows="left|top"
+   height="16"
+   layout="topleft"
+   left="10"
+   top_pad="13"
+   width="50">
+   Keyword:
+  </text>
+  <line_editor
+   name="autoreplace_keyword"
+   follows="left|top"
+   height="23"
+   layout="topleft"
+   left="100"
+   max_length_bytes="255"
+   top_delta="-5"
+   width="150"
+   />
+  <text
+   type="string"
+   follows="left|top"
+   height="16"
+   layout="topleft"
+   left="10"
+   right="90"
+   top_pad="10"
+   >
+   Replacement:
+  </text>
+  <line_editor
+   name="autoreplace_replacement"
+   follows="left|top"
+   height="23"
+   layout="topleft"
+   left="100"
+   max_length_bytes="255"
+   top_delta="-5"
+   width="280"
+   />
+  <button
+   top_delta="0"
+   right="-10"
+   height="22"
+   width="90"
+   enabled="false"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_save_entry"
+   label="Save Entry"
+   tool_tip="Save this entry."/>
+  <view_border
+   top_pad="10"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor4"/>
+  <button
+   top_pad="10"
+   right="380"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_save_changes"
+   label="Save Changes"
+   tool_tip="Save all changes."/>
+  <button
+   top_delta="0"
+   right="480"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="autoreplace_cancel"
+   label="Cancel"
+   tool_tip="Discard all changes."/>
+</floater>
+<!--
+  <text 
+   top_pad="10"
+   left="10"
+   height="16"
+   width="260"
+   follows="left|top"
+   halign="center"
+   mouse_opaque="true"
+   name="autoreplace_text2">
+    Entries
+  </text>
+-->
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 688a01ce7bc2d05a8b43a0ef906a73509c312bf3..405557242fa8c47465c5d6bf828a98b02f120fd4 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -46,6 +46,7 @@
         left="0"
         max_length_bytes="1023"
         name="chat_box"
+        spellcheck="true"
         text_pad_left="5"
         text_pad_right="25"
         tool_tip="Press Enter to say, Ctrl+Enter to shout"
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 ca73883e5346c3aed135449f0731a09025594e0c..040b66623e72940042b0416980bf838890a5fc15 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -46,7 +46,7 @@
        tab_group="2"
        top="0"
        height="200"
-	     width="254"
+	     width="244"
        user_resize="true">
         <button
           height="20"
@@ -73,18 +73,20 @@
          parse_highlights="true"
          parse_urls="true"
         left="1"
-         width="249">
+         width="238">
         </chat_history>
         <line_editor
          bottom="0"
+         left="3"
          follows="left|right|bottom"
 	 font="SansSerifSmall"
          height="20"
          label="To"
          layout="bottomleft"
          name="chat_editor"
+         spellcheck="true"
          tab_group="3"
-         width="249">
+         width="236">
         </line_editor>
     </layout_panel>
   </layout_stack>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 0e211551e67dc099c159b46688f30d1405590dd7..5e92a1225176912b1b98e516e07c6764b254462e 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1,8 +1,16 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater can_close="true" can_drag_on_left="false" can_minimize="false"
-     can_resize="false" height="480" min_height="480" min_width="940"
-     name="Model Preview" title="UPLOAD MODEL" width="940"
-      help_topic="upload_model" >
+<floater
+ can_close="true"
+ can_drag_on_left="false"
+ can_minimize="false"
+ can_resize="false"
+ height="480"
+ min_height="480"
+ width="980"
+ min_width="980"
+ name="Model Preview"
+ title="UPLOAD MODEL"
+ help_topic="upload_model" >
 
   <string name="status_idle"></string>
   <string name="status_parse_error">Error: Dae parsing issue - see log for details.</string>
@@ -98,7 +106,7 @@
       top_pad="15"
       left="0"
       height="300"
-      width="625"
+      width="635"
       name="import_tab"
       tab_position="top">
       <!-- LOD PANEL -->
@@ -116,13 +124,13 @@
              left="3"
              name="lod_tab_border"
              top_pad="0"
-             width="619" />
+             width="629" />
           <text
            follows="left|top"
            height="18"
            initial_value="Source"
            layout="topleft"
-           left="75"
+           left="85"
            name="source"
            text_color="ModelUploaderLabels"
            top="15"
@@ -165,7 +173,7 @@
              top_pad="10"
              valign="top"
              value="High"
-             width="65" />
+             width="75" />
             <combo_box
              follows="top|left"
              height="20"
@@ -175,10 +183,10 @@
              top_delta="-3"
              width="135">
                 <item
-                 id="Load from file"
+                 name="Load from file"
                  value="Load from file" />
                 <item
-                 id="Generate"
+                 name="Generate"
                  value="Generate" />
             </combo_box>
             <line_editor
@@ -210,10 +218,10 @@
              visible="false"
              width="135">
                 <item
-                 id="Triangle Limit"
+                 name="Triangle Limit"
                  value="Triangle Limit" />
                 <item
-                 id="Error Threshold"
+                 name="Error Threshold"
                  value="Error Threshold" />
             </combo_box>
             <spinner
@@ -290,7 +298,7 @@
              top_pad="15"
              valign="top"
              value="Medium"
-             width="65" />
+             width="75" />
             <combo_box
              follows="top|left"
              height="20"
@@ -300,13 +308,13 @@
              top_delta="-3"
              width="135">
                 <item
-                 id="Load from file"
+                 name="Load from file"
                  value="Load from file" />
                 <item
-                 id="Generate"
+                 name="Generate"
                  value="Generate" />
                 <item
-                 id="Use LoD above"
+                 name="Use LoD above"
                  value="Use LoD above" />
             </combo_box>
             <line_editor
@@ -339,10 +347,10 @@
              top_delta="0"
              width="135">
                 <item
-                 id="Triangle Limit"
+                 name="Triangle Limit"
                  value="Triangle Limit" />
                 <item
-                 id="Error Threshold"
+                 name="Error Threshold"
                  value="Error Threshold" />
             </combo_box>
             <spinner
@@ -418,7 +426,7 @@
              top_pad="15"
              valign="top"
              value="Low"
-             width="65" />
+             width="75" />
             <combo_box
              follows="top|left"
              height="20"
@@ -428,13 +436,13 @@
              top_delta="-3"
              width="135">
                 <item
-                 id="Load from file"
+                 name="Load from file"
                  value="Load from file" />
                 <item
-                 id="Generate"
+                 name="Generate"
                  value="Generate" />
                 <item
-                 id="Use LoD above"
+                 name="Use LoD above"
                  value="Use LoD above" />
             </combo_box>
             <line_editor
@@ -467,10 +475,10 @@
              top_delta="0"
              width="135">
                 <item
-                 id="Triangle Limit"
+                 name="Triangle Limit"
                  value="Triangle Limit" />
                 <item
-                 id="Error Threshold"
+                 name="Error Threshold"
                  value="Error Threshold" />
             </combo_box>
             <spinner
@@ -546,7 +554,7 @@
              top_pad="15"
              valign="top"
              value="Lowest"
-             width="65" />
+             width="75" />
             <combo_box
              follows="top|left"
              height="20"
@@ -556,13 +564,13 @@
              top_delta="-3"
              width="135">
                 <item
-                 id="Load from file"
+                 name="Load from file"
                  value="Load from file" />
                 <item
-                 id="Generate"
+                 name="Generate"
                  value="Generate" />
                 <item
-                 id="Use LoD above"
+                 name="Use LoD above"
                  value="Use LoD above" />
             </combo_box>
             <line_editor
@@ -595,10 +603,10 @@
              top_delta="0"
              width="135">
                 <item
-                 id="Triangle Limit"
+                 name="Triangle Limit"
                  value="Triangle Limit" />
                 <item
-                 id="Error Threshold"
+                 name="Error Threshold"
                  value="Error Threshold" />
             </combo_box>
             <spinner
@@ -1201,7 +1209,7 @@
          name="calculate_btn"
          top="3"
          height="20"
-         width="150"
+         width="165"
          tool_tip="Calculate weights &amp;fee"/>
        <button
          follows="top|left"
@@ -1234,7 +1242,7 @@
          right="-2"
          top="3"
          height="20"
-         width="155"/>
+         width="275"/>
        <!-- ========== WEIGHTS ==========-->
        <text
          follows="top|left"
@@ -1343,7 +1351,7 @@
   layout="topleft"
   name="right_panel"
   top_pad="5"
-  width="290">
+  width="340">
     <combo_box
       top_pad="3"
       follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
deleted file mode 100644
index 62b8c5f96edd46c2fac913b37c1136059206889f..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml
+++ /dev/null
@@ -1,841 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- layout="topleft"
- name="Model Wizard"
- help_topic="model_wizard"
- bg_opaque_image_overlay="0.5 0.5 0.5 1"
- height="480"
- save_rect="true"
- title="UPLOAD MODEL WIZARD"
- width="535">
-	<button
-	 top="32"
-	 tab_stop="false"
-	 left="410"
-	 height="32"
-	 name="upload_btn"
-	 enabled="false"
-	 label="5. Upload"
-	 border="false"
-	 image_unselected="BreadCrumbBtn_Right_Off"
-	 image_selected="BreadCrumbBtn_Right_Press"
-	 image_hover_unselected="BreadCrumbBtn_Right_Over"
-	 image_disabled="BreadCrumbBtn_Right_Disabled"
-	 image_disabled_selected="BreadCrumbBtn_Right_Disabled"
-	 width="110">
-		<button.commit_callback
-		function="Wizard.Upload"/>
-	</button>
-	<button
-	 top="32"
-	 left="310"
-	 height="32"
-	 tab_stop="false"
-	 name="review_btn"
-	 label="4. Review"
-	 enabled="false"
-	 border="false"
-	 image_unselected="BreadCrumbBtn_Middle_Off"
-	 image_selected="BreadCrumbBtn_Middle_Press"
-	 image_hover_unselected="BreadCrumbBtn_Middle_Over"
-	 image_disabled="BreadCrumbBtn_Middle_Disabled"
-	 image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
-	 width="110">
-		<button.commit_callback
-		function="Wizard.Review"/>
-	</button>
-	<button
-	 top="32"
-	 left="210"
-	 height="32"
-	 name="physics_btn"
-	 label="3. Physics"
-	 tab_stop="false"
-	 enabled="false"
-	 border="false"
-	 image_unselected="BreadCrumbBtn_Middle_Off"
-	 image_selected="BreadCrumbBtn_Middle_Press"
-	 image_hover_unselected="BreadCrumbBtn_Middle_Over"
-	 image_disabled="BreadCrumbBtn_Middle_Disabled"
-	 image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
-	 width="110">
-		<button.commit_callback
-		function="Wizard.Physics"/>
-	</button>
-	<button
-	 top="32"
-	 left="115"
-	 name="optimize_btn"
-	 label="2. Optimize"
-	 tab_stop="false"
-	 height="32"
-	 border="false"
-	 image_unselected="BreadCrumbBtn_Middle_Off"
-	 image_selected="BreadCrumbBtn_Middle_Press"
-	 image_hover_unselected="BreadCrumbBtn_Middle_Over"
-	 image_disabled="BreadCrumbBtn_Middle_Disabled"
-	 image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
-	 width="110">
-		<button.commit_callback
-		function="Wizard.Optimize"/>
-	</button>
-	<button
-	 top="32"
-	 left="15"
-	 name="choose_file_btn"
-	 tab_stop="false"
-	 enabled="false"
-	 label="1. Choose File"
-	 height="32"
-	 image_unselected="BreadCrumbBtn_Left_Off"
-	 image_selected="BreadCrumbBtn_Left_Press"
-	 image_hover_unselected="BreadCrumbBtn_Left_Over"
-	 image_disabled="BreadCrumbBtn_Left_Disabled"
-	 image_disabled_selected="BreadCrumbBtn_Left_Disabled"
-	 width="110">
-		<button.commit_callback
-		function="Wizard.Choose"/>
-	</button>
-	<panel
-		 height="388"
-		 top_pad="0"
-		 name="choose_file_panel"
-		 visible="false"
-		 width="535"
-		 left="0">
-		<panel
-		 height="22"
-		 top_pad="15"
-		 width="505"
-		 name="choose_file_header_panel"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true"
-		 left="15">
-			<text
-			 width="200"
-			 left="10"
-			 top="3"
-			 name="choose_file_header_text"
-			 text_color="White"
-			 height="10"
-			 font="SansSerifBig"
-			 layout="topleft">
-				Choose model file
-			</text>
-		</panel>
-		<panel
-		 top_pad="14"
-		 left="15"
-		 height="310"
-		 width="505"
-		 name="choose_file_content"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true">
-            <text
-			 height="32"
-			 left="10"
-			 name="advanced_users_text"
-			 text_color="White"
-			 top="15"
-			 width="320"
-			 word_wrap="true">
-				Advanced users: If you are familiar with 3D content creation tools you may wish to use the Advanced Uploader.
-			</text>
-			<button
-			 follows="left|top"
-			 height="20"
-			 label="Switch to Advanced"
-			 layout="topleft"
-			 left_delta="0"
-			 name="switch_to_advanced"
-			 top_pad="5"
-			 width="130">
-			</button>
-			<text
-			 type="string"
-			 length="1"
-			 text_color="White" 
-			 follows="left|top"
-			 top_pad="30"
-			 height="10"
-			 layout="topleft"
-			 left_delta="0"
-			 name="Cache location"
-			 width="320">
-				Choose model file to upload
-			</text>
-			<line_editor
-			 border_style="line"
-			 border_thickness="1"
-			 follows="left|top"
-			 font="SansSerifSmall"
-			 height="20"
-			 layout="topleft"
-			 left_delta="0"
-			 max_length="4096"
-			 name="lod_file"
-			 top_pad="5"
-			 width="230" />
-			<button
-			 follows="left|top"
-			 height="23"
-			 label="Browse..."
-			 label_selected="Browse..."
-			 layout="topleft"
-			 left_pad="5"
-			 name="browse"
-			 top_delta="-1"
-			 width="85">
-			</button>
-			<text
-			 type="string"
-			 length="1"
-			 text_color="White" 
-			 follows="left|top"
-			 top_pad="5"
-			 height="10"
-			 layout="topleft"
-			 left="10"
-			 name="Model types"
-			 width="320">
-				Second Life supports COLLADA (.dae) files
-			</text>
-			<!-- Placeholder panel for 3D preview render -->
-			<panel
-			 top="30"
-			 right="-10"
-			 name="choose_file_preview_panel"
-			 bevel_style="none"
-			 highlight_light_color="0.09 0.09 0.09 1"
-			 border="true"
-			 border_style="line"
-			 height="150"
-			 follows="all"
-			 width="150">
-			</panel>
-			<text
-			 top_pad="10"
-			 width="130"
-			 height="14"
-			 left_delta="0"
-			 text_color="White"
-			 word_wrap="true">
-				Dimensions (meters):
-			</text>
-			<text
-			 top_pad="0"
-			 width="160"
-			 height="15"
-			 font="SansSerifSmallBold" 
-			 text_color="White"
-			 name="dimensions"
-			 left_delta="0">
-				X         Y         Z 
-			</text>
-			<text
-			 top_delta="0"
-			 width="160"
-			 height="15"
-			 name="dimension_x"
-			 left="356"/>
-			<text
-			 top_delta="0"
-			 width="160"
-			 height="15"
-			 name="dimension_y"
-			 left="403"/>
-			<text
-			 top_delta="0"
-			 width="160"
-			 height="15"
-			 name="dimension_z"
-			 left="450"/>
-            <text
-             height="16"
-             left="10"
-             name="warning_label"
-             text_color="Yellow"
-             top="200"
-             visible="false"
-             width="320">
-                WARNING:
-            </text>
-            <text
-             height="50"
-             left="10"
-             name="warning_text"
-             top_pad="0"
-             visible="false"
-             width="320"
-             word_wrap="true">
-                You will not be able to complete the final step of uploading this model to the Second Life servers. [secondlife:///app/floater/learn_more Find out how] to set up your account for mesh model uploads. 
-            </text>
-		</panel>
-	</panel>
-
-
-	<panel
-		 height="388"
-		 top_delta="0"
-		 name="optimize_panel"
-		 visible="true"
-		 width="535"
-		 left="0">
-		<panel
-		 height="22"
-		 top_pad="15"
-		 name="optimize_header_panel"
-		 width="505"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true"
-		 left="15">
-			<text
-			 width="200"
-			 left="10"
-			 name="optimize_header_text"
-			 top="3"
-			 text_color="White"
-			 height="10"
-			 font="SansSerifBig"
-			 layout="topleft">
-				Optimize model
-			</text>
-		</panel>
-		<text
-		 top_pad="14"
-		 width="460"
-		 height="20"
-		 font="SansSerifSmall"
-		 layout="topleft"
-		 name="optimize_description"
-		 word_wrap="true"
-		 left_delta="5">
-			We have optimized the model for performance. Adjust it further if you wish.
-		</text>
-		<panel
-		 top_delta="40"
-		 visible="false"
-		 left="15"
-		 height="270"
-		 width="505"
-		 name="optimize_content"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true">
-			<text
-			 top="20"
-			 width="300"
-			 height="12"
-			 font="SansSerifBold"
-			 left="112">Generating Level of Detail</text>
-			<progress_bar
-			  name="optimize_progress_bar"
-              image_fill="model_wizard\progress_light.png"
-			  color_bg="1 1 1 1"
-			  color_bar="1 1 1 0.96"
-			  follows="left|right|top"
-			  width="260"
-			  height="16"
-			  image_bar="model_wizard\progress_bar_bg.png"
-			  top_pad="14"
-			  left="110"/>
-			<icon
-			 top_pad="10"
-			 left_delta="0"
-			 width="13"
-			 height="12"
-			 image_name="model_wizard\check_mark.png"/>
-			<text
-			 top_delta="0"
-			 left_delta="18"
-			 name="high_detail_text"
-			 width="200"
-			 height="14">Generate Level of Detail: High</text>
-			<icon
-			 top_pad="10"
-			 left_delta="-18"
-			 width="13"
-			 height="12"
-			 image_name="model_wizard\check_mark.png"/>
-			<text
-			 top_delta="0"
-			 left_delta="18"
-			 name="medium_detail_text"
-			 width="200"
-			 height="14">Generate Level of Detail: Medium</text>
-			<icon
-			 top_pad="10"
-			 left_delta="-18"
-			 width="13"
-			 height="12"
-			 image_name="model_wizard\check_mark.png"/>
-			<text
-			 top_delta="0"
-			 left_delta="18"
-			 name="low_detail_text"
-			 width="200"
-			 height="14">Generate Level of Detail: Low</text>
-			<icon
-			 top_pad="10"
-			 left_delta="-18"
-			 width="13"
-			 height="12"
-			 image_name="model_wizard\check_mark.png"/>
-			<text
-			 top_delta="0"
-			 left_delta="18"
-			 name="lowest_detail_text"
-			 width="200"
-			 height="14">Generate Level of Detail: Lowest</text>
-		</panel>
-		<panel
-				 top_delta="0"
-				 left_delta="0"
-				 height="270"
-				 width="505"
-				 name="content2"
-				 bg_opaque_color="DkGray2"
-				 background_visible="true"
-				 background_opaque="true">
-			<text top="69" left="10" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Performance</text>
-			<text top="85" left="10" width="120" word_wrap="true" font="SansSerifSmall" height="40">Faster rendering
-Less detail
-Lower prim weight</text>
-			<text top="69" left="184" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Accuracy</text>
-			<text top="85" left="184" width="120" word_wrap="true" font="SansSerifSmall" height="40">Slower rendering
-More detail
-Higher prim weight</text>
-
-          <slider
-		   follows="left|top"
-		   height="20"
-		   increment="1"
-		   layout="topleft"
-		   left="10"
-		   max_val="2"
-		   initial_value="1"
-		   min_val="0"
-		   name="accuracy_slider"
-		   show_text="false"
-		   top="130"
-		   width="290" />
-          <text 
-			font="SansSerifSmall" 
-			top_pad="0"  
-			width="5" 
-			left_delta="6" 
-			height="4">'  
-          </text>
-          <text 
-			font="SansSerifSmall" 
-			top_delta="0"  
-			width="5" 
-			left_delta="137" 
-			height="4">'  
-          </text>
-          <text 
-			font="SansSerifSmall" 
-			top_delta="0"  
-			width="5" 
-			left_delta="137" 
-			height="4">'  
-          </text>
-          <button
-			follows="left|top"
-			height="20"
-			label="Recalculate Geometry"
-			layout="topleft"
-			left="80"
-			name="recalculate_geometry_btn"
-			top_pad="15"
-            width="150">
-          </button>
-			<text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
-				Geometry preview
-			</text>
-			<panel
-				 right="-10"
-				 top="32"
-				 name="optimize_preview_panel"
-				 bevel_style="none"
-				 highlight_light_color="0.09 0.09 0.09 1"
-				 border_style="line"
-				 border="true"
-				 height="185"
-				 follows="all"
-				 width="185">
-			</panel>
-			<combo_box left_delta="75" top_pad="10"  follows="left|top" list_position="below" height="22"
-	     name="preview_lod_combo" width="110" tool_tip="LOD to view in preview render">
-				<combo_item name="high">
-					High detail
-				</combo_item>
-				<combo_item name="medium">
-					Medium detail
-				</combo_item>
-				<combo_item name="low">
-					Low detail
-				</combo_item>
-				<combo_item name="lowest">
-					Lowest detail
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-
-	<panel
-		 height="388"
-		 top_delta="0"
-		 name="physics_panel"
-		 visible="false"
-		 width="535"
-		 left="0">
-		<panel
-		 height="22"
-		 top_pad="15"
-		 name="physics_header_panel"
-		 width="505"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true"
-		 left="15">
-			<text
-			 width="200"
-			 left="10"
-			 name="physics_header_text"
-			 top="3"
-			 height="10"
-			 font="SansSerifBig"
-			 text_color="White" 
-			 layout="topleft">
-				Adjust physics
-			</text>
-		</panel>
-		<text
-		 top_pad="10"
-		 width="474"
-		 height="50"
-		 font="SansSerifSmall"
-		 layout="topleft"
-		 name="physics_description"
-		 word_wrap="true"
-		 left_delta="5">
-			We will create a shape for the outer hull of the model. Adjust the shape's detail level as needed for the intended purpose of your model.
-		</text>
-    <panel
-		 top_delta="44"
-		 left="15"
-		 height="270"
-		 width="505"
-		 name="physics_content"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true">
-      <text top="10" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Performance</text>
-      <text top="26" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Faster rendering
-Less detail
-Lower prim weight</text>
-      <text top="174" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Accuracy</text>
-      <text top="190" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Slower rendering
-More detail
-Higher prim weight</text>
-
-      <slider
-		   follows="left|top"
-		   height="190"
-		   increment=".1"
-		   layout="topleft"
-		   left="140"
-		   max_val="1"
-		   initial_value="0.5"
-		   min_val="0"
-		   name="physics_slider"
-		   orientation="vertical"
-		   show_text="false"
-		   top="25"
-		   width="22" />
-      <text top="10" width="120" word_wrap="true" left_pad="10" height="50">Examples:
-Moving objects
-Flying objects
-Vehicles</text>
-      <text top="95" width="120" word_wrap="true" left_delta="0" height="50">Examples:
-Small static objects
-Less detailed objects
-Simple furniture</text>
-      <text top="180" width="120" word_wrap="true" left_delta="0" height="50">Examples:
-Static objects
-Detailed objects
-Buildings</text>
-          <button
-			follows="left|top"
-			height="20"
-			label="Recalculate physics"
-			layout="topleft"
-			left="80"
-			name="recalculate_physics_btn"
-			top_pad="10"
-            width="150">
-          </button>
-          <button
-            enabled="false"
-			follows="left|top"
-			height="20"
-			label="Recalculating..."
-			layout="topleft"
-			left_delta="0"
-			name="recalculating_physics_btn"
-			top_delta="0"
-			visible="false"
-            width="150">
-          </button>
-			<text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
-				Physics preview
-			</text>
-			<panel
-				 right="-10"
-				 top="32"
-				 name="physics_preview_panel"
-				 bevel_style="none"
-				 highlight_light_color="0.09 0.09 0.09 1"
-				 border_style="line"
-				 border="true"
-				 height="185"
-				 follows="all"
-				 width="185">
-			</panel>
-			<combo_box left_delta="75" top_pad="10"  follows="left|top" list_position="below" height="22"
-	     name="preview_lod_combo2" width="110" tool_tip="LOD to view in preview render">
-				<combo_item name="high">
-					High detail
-				</combo_item>
-				<combo_item name="medium">
-					Medium detail
-				</combo_item>
-				<combo_item name="low">
-					Low detail
-				</combo_item>
-				<combo_item name="lowest">
-					Lowest detail
-				</combo_item>
-			</combo_box>
-    </panel>
-	</panel>
-
-	<panel
-		 height="388"
-		 top_delta="0"
-		 name="review_panel"
-		 visible="false"
-		 width="535"
-		 left="0">
-		<panel
-		 height="22"
-		 top_pad="15"
-		 name="review_header_panel"
-		 width="505"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true"
-		 left="15">
-			<text
-			 width="200"
-			 left="10"
-			 name="review_header_text"
-			 text_color="White" 
-			 top="3"
-			 height="10"
-			 font="SansSerifBig"
-			 layout="topleft">
-				Review
-			</text>
-		</panel>
-		<panel
-		 top_pad="14"
-		 left="15"
-		 height="310"
-		 width="505"
-		 name="review_content"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true">
-			<text
-			 top="20"
-			 width="485"
-			 font="SansSerifMedium"
-			 text_color="White"
-			 left="10"
-			 name="review_prim_equiv"
-			 height="16">Impact to parcel/region: [EQUIV] prim equivalents
-			</text>
-			<text
-			 top_pad="20"
-			 width="485"
-			 font="SansSerifMedium"
-			 text_color="White"
-			 left="10"
-			 name="review_fee"
-			 height="16">Your account will be charged an upload fee of L$ [FEE].
-			</text>
-			<text 
-			 top_pad="20"
-			 width="485"
-			 font="SansSerifMedium"
-			 text_color="White"
-			 left="10"
-			 name="review_confirmation"
-			 height="32"
-			 word_wrap="true">By clicking the upload button, you confirm that you have the appropriate rights to the material contained in the model.
-			</text>
-      </panel>
-	</panel>
-
-
-
-
-	<panel
-		 height="388"
-		 top_delta="0"
-		 name="upload_panel"
-		 visible="false"
-		 width="535"
-		 left="0">
-		<panel
-		 height="22"
-		 top_pad="15"
-		 name="upload_header_panel"
-		 width="505"
-		 bg_opaque_color="DkGray2"
-		 background_visible="true"
-		 background_opaque="true"
-		 left="15">
-			<text
-			 width="200"
-			 left="10"
-			 name="upload_header_text"
-			 top="3"
-			 text_color="White" 
-			 height="10"
-			 font="SansSerifBig"
-			 layout="topleft">
-				Upload complete
-			</text>
-		</panel>
-		<text
-		 top_pad="14"
-		 width="495"
-		 height="16"
-		 font="SansSerifMedium"
-		 layout="topleft"
-		 name="model_uploaded_text"
-		 text_color="White"
-		 word_wrap="true"
-		 left="25">
-			Your model has been uploaded.
-		</text>
-		<text
-		 top_pad="5"
-		 width="495"
-		 height="16"
-		 font="SansSerifMedium"
-		 layout="topleft"
-		 name="inventory_text"
-		 text_color="White"
-		 word_wrap="true"
-		 left="25">
-			You will find it in the Objects folder in your inventory.
-		</text>
-		<text
-		 top_pad="20"
-		 width="495"
-		 font="SansSerifMedium"
-		 text_color="White"
-		 left="25"
-		 name="charged_fee"
-		 height="16">Your account has been charged L$ [FEE].
-		</text>
-	</panel>
-
-
-
-	<button
-	 top="440"
-	 right="-285"
-	 width="90"
-	 height="22"
-	 name="back"
-	 label="&lt;&lt; Back" />
-	<button
-	 top_delta="0"
-	 right="-190"
-	 width="90"
-	 height="22"
-	 name="next"
-	 label="Next &gt;&gt; " />
-	<button
-	 top_delta="0"
-	 left_delta="0"
-	 width="160"
-	 height="22"
-	 name="calculate"
-	 label="Calculate weights &amp; fee &gt;&gt; " />
-	<button
-	 enabled="false"
-	 visible="false"
-	 top_delta="0"
-	 left_delta="0"
-	 width="160"
-	 height="22"
-	 name="calculating"
-	 label="Calculating... " />
-	<button
-	 enabled="false"
-	 top_delta="0"
-	 right="-150"
-	 width="90"
-	 height="22"
-	 visible="false" 
-	 name="upload" 
-	 tool_tip="Upload to simulator"
-	 label="Upload" />
-	<button
-	 top_delta="0"
-	 right="-15"
-	 width="90"
-	 height="22"
-	 name="cancel"
-	 label="Cancel" />
-	<button
-	 top_delta="0"
-	 right="-15"
-	 width="90"
-	 height="22"
-	 name="close"
-	 visible="false" 
-	 label="Close" />
-	<spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>
-
-	<string name="status_idle">Idle</string>
-  <string name="status_parse_error">Dae parsing issue - see log for details.</string>
-	<string name="status_reading_file">Loading...</string>
-	<string name="status_generating_meshes">Generating Meshes...</string>
-	<string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string>
-	<string name="bad_element">Error: element is invalid</string>
-	<string name="high">High</string>
-	<string name="medium">Medium</string>
-	<string name="low">Low</string>
-	<string name="lowest">Lowest</string>
-	<string name="mesh_status_good">Ship it!</string>
-	<string name="mesh_status_na">N/A</string>
-	<string name="mesh_status_none">None</string>
-	<string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string>
-	<string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string>
-	<string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string>
-	<string name="mesh_status_missing_lod">Missing required level of detail.</string>
-	<string name="layer_all">All</string>
-	<!-- Text to display in physics layer combo box for "all layers" -->
-
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
index 184f29625595a485568d60304ff98e526df51ba0..ea44fd493ec01de3a596bbc1615712aaf0d61981 100644
--- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
@@ -6,7 +6,7 @@
  height="570"
  help_topic="sidebar_inventory"
  min_width="333"
- min_height="440"
+ min_height="560"
  name="floater_my_inventory"
  save_rect="true"
  save_visibility="true"
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index be3b2d179d5155acaf9a359baac3dc9498a7a6d9..2e1c8ce6707354e69c065b7f5b4a779aadc76ea3 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -70,6 +70,7 @@
      max_length="65536"
      name="Notecard Editor"
      parse_urls="false" 
+     spellcheck="true"
      tab_group="1"
      top="46"
      width="392"
diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck.xml b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
new file mode 100644
index 0000000000000000000000000000000000000000..76a350dd294729e73dfa72559a2c26c3e730ba45
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ save_rect="true"
+ help_topic="spelling_settings"
+ can_resize="false"
+ height="315"
+ width="490"
+ name="spellcheck_floater"
+ title="Spell Checker Settings">
+  <check_box
+   bottom_delta="30"
+   control_name="SpellCheck"
+   left_delta="15"
+   height="16"
+   width="100"
+   follows="left|top"
+   label="Enable spell checker"
+   name="spellcheck_enable" />
+  <view_border
+   top_pad="10"
+   left="2"
+   height="0"
+   width="491"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor1"/>
+  <text
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="10"
+   layout="topleft"
+   left="38"
+   mouse_opaque="false"
+   name="spellcheck_main"
+   top_pad="15"
+   type="string"
+   width="90"
+  >
+    Main dictionary :
+  </text>
+  <combo_box
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="23"
+   layout="topleft"
+   left_pad="10"
+   name="spellcheck_main_combo"
+   top_pad="-15"
+   width="175"
+  />
+  <text
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="10"
+   label="Logs:"
+   layout="topleft"
+   left="38"
+   mouse_opaque="false"
+   name="spellcheck_additional"
+   top_pad="15"
+   type="string"
+   width="190"
+  >
+    Additional dictionaries :
+  </text>
+  <text
+   follows="top|left"
+   height="12"
+   layout="topleft"
+   left="55"
+   length="1"
+   name="spellcheck_available"
+   top_pad="10"
+   type="string"
+   width="175">
+      Available
+  </text>
+  <text
+   follows="top|left"
+   height="12"
+   type="string"
+   left_pad="45"
+   length="1"
+   layout="topleft"
+   name="spellcheck_active"
+   width="175">
+      Active
+  </text>
+  <scroll_list
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="155"
+   layout="topleft"
+   left="55"
+   multi_select="true"
+   name="spellcheck_available_list"
+   sort_column="0"
+   sort_ascending="true" 
+   width="175" />
+  <button
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="26"
+   image_overlay="Arrow_Right"
+   hover_glow_amount="0.15"
+   layout="topleft"
+   left_pad="10"
+   name="spellcheck_moveright_btn"
+   top_delta="50"
+   width="25">
+  </button>
+  <button
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="26"
+   image_overlay="Arrow_Left"
+   hover_glow_amount="0.15"
+   layout="topleft"
+   name="spellcheck_moveleft_btn"
+   top_delta="30"
+   width="25">
+  </button>
+  <scroll_list
+   enabled_control="SpellCheck"
+   follows="top|left"
+   height="155"
+   layout="topleft"
+   left_pad="10"
+   multi_select="true"
+   name="spellcheck_active_list"
+   sort_column="0"
+   sort_ascending="true" 
+   top_pad="-105"
+   width="175"
+  />
+  <button
+   enabled="false"
+   follows="left|top"
+   height="23"
+   label="Remove"
+   layout="topleft"
+   left="55"
+   name="spellcheck_remove_btn"
+   top_pad="5"
+   width="80" />
+  <button
+   follows="left|top"
+   height="23"
+   label="Import..."
+   layout="topleft"
+   left_pad="15"
+   name="spellcheck_import_btn"
+   top_delta="0"
+   width="80" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b54090015d62f85874caef7e283dbbe6f86456a7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ bottom="275"
+ left="300"
+ can_resize="false"
+ height="140"
+ width="400"
+ name="spellcheck_import"
+ title="Import Dictionary">
+  <text
+   follows="top|left"
+   height="16"
+   layout="topleft"
+   left="25"
+   top="15"
+   type="string"
+   width="65">
+   Dictionary:
+  </text>
+  <line_editor
+   enabled="false"
+   follows="left|top"
+   height="23"
+   layout="topleft"
+   left_pad="10"
+   max_length_bytes="255"
+   name="dictionary_path"
+   top_delta="-5"
+   width="200" />
+  <button
+   follows="left|top"
+   height="23"
+   label="Browse"
+   label_selected="Browse"
+   layout="topleft"
+   left_pad="5"
+   name="dictionary_path_browse"
+   top_delta="0"
+   width="75" />
+  <text
+   follows="top|left"
+   height="16"
+   layout="topleft"
+   left="25"
+   top_pad="8"
+   type="string"
+   width="65">
+   Name:
+  </text>
+  <line_editor
+   enabled="false"
+   follows="left|top"
+   height="23"
+   layout="topleft"
+   left_pad="10"
+   max_length_bytes="255"
+   name="dictionary_name"
+   top_delta="-5"
+   width="200" />
+  <text
+   follows="top|left"
+   height="16"
+   layout="topleft"
+   left="25"
+   top_pad="8"
+   type="string"
+   width="65">
+   Language:
+  </text>
+  <line_editor
+   follows="left|top"
+   height="23"
+   layout="topleft"
+   left_pad="10"
+   max_length_bytes="255"
+   name="dictionary_language"
+   top_delta="-5"
+   width="200" />
+  <view_border
+   top_pad="10"
+   left="2"
+   height="0"
+   width="396"
+   follows="left|top"
+   bevel_style="none"
+   border_thickness="1"
+   mouse_opaque="false"
+   name="divisor"/>
+  <button
+   top_pad="10"
+   right="280"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="ok_btn"
+   label="Import" />
+  <button
+   top_delta="0"
+   right="380"
+   height="22"
+   width="90"
+   enabled="true"
+   follows="left|top"
+   mouse_opaque="true"
+   halign="center"
+   scale_image="true"
+   name="cancel_btn"
+   label="Cancel" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index ffb8b842f0cbb3920eb1507d22de4fa25d5fc1cf..6021ba0a5ab8b8ebea4da81876c637009ba4fbd0 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -134,6 +134,16 @@
      top_delta="-25"
      name="Pipette"
      width="28" />
+   <text
+     follows="left|bottom"
+     height="20"
+     layout="topleft"
+     left="8"
+     name="preview_disabled"
+     top="266"
+     value="Preview Disabled"
+     visible="false"
+     width="120" />
     <filter_editor
      follows="left|top|right"
      height="23"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
index 44b6a63bcae5a98b07899f2cbdd4c27ac1b3b655..f3f8d4ddca4c875a36bd8e08e00db2fc5c7161b2 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
@@ -1,341 +1,341 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- can_minimize="false"
- height="550"
- layout="topleft"
- name="TexFetchDebugger"
- help_topic="texfetchdebugger"
- title="Texture Fetching Debugger"
- width="540">
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left="10"
-   name="total_num_fetched_label"
-   top="30"
-   width="400">
-    1, Total number of fetched textures: [NUM]
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_num_fetching_requests_label"
-   top_delta="25"
-   width="400">
-    2, Total number of fetching requests: [NUM]
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_num_cache_hits_label"
-   top_delta="25"
-   width="400">
-    3, Total number of cache hits: [NUM]
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_num_visible_tex_label"
-   top_delta="25"
-   width="400">
-    4, Total number of visible textures: [NUM]
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_num_visible_tex_fetch_req_label"
-   top_delta="25"
-   width="450">
-    5, Total number of visible texture fetching requests: [NUM]
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_fetched_data_label"
-   top_delta="25"
-   width="530">
-    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_fetched_vis_data_label"
-   top_delta="25"
-   width="480">
-    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_fetched_rendered_data_label"
-   top_delta="25"
-   width="530">
-    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_time_cache_read_label"
-   top_delta="25"
-   width="400">
-    9, Total time on cache readings: [TIME] seconds
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_time_cache_write_label"
-   top_delta="25"
-   width="400">
-    10, Total time on cache writings: [TIME] seconds
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_time_decode_label"
-   top_delta="25"
-   width="400">
-    11, Total time on decodings: [TIME] seconds
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_time_gl_label"
-   top_delta="25"
-   width="400">
-    12, Total time on gl texture creation: [TIME] seconds
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_time_http_label"
-   top_delta="25"
-   width="400">
-    13, Total time on HTTP fetching: [TIME] seconds
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="25"
-   layout="topleft"
-   left_delta="0"
-   name="total_time_fetch_label"
-   top_delta="25"
-   width="400">
-    14, Total time on entire fetching: [TIME] seconds
-  </text>
-  <text
-  type="string"
-  length="1"
-  follows="left|top"
-  height="25"
-  layout="topleft"
-  left_delta="0"
-  name="total_time_refetch_vis_cache_label"
-  top_delta="25"
-  width="540">
-    15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
-  </text>
-  <text
-  type="string"
-  length="1"
-  follows="left|top"
-  height="25"
-  layout="topleft"
-  left_delta="0"
-  name="total_time_refetch_vis_http_label"
-  top_delta="25"
-  width="540">
-    16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
-  </text>
-  <spinner
-     decimal_digits="2"
-     follows="left|top"
-     height="20"
-     increment="0.01"
-     initial_value="1.0"
-     label="17, Ratio of Texel/Pixel:"
-     label_width="130"
-     layout="topleft"
-     left_delta="0"
-     max_val="10.0"
-     min_val="0.01"
-     name="texel_pixel_ratio"
-     top_delta="30"
-     width="200">
-    <spinner.commit_callback
-		function="TexFetchDebugger.ChangeTexelPixelRatio" />
-  </spinner>
-  <button
-   follows="left|top"
-   height="20"
-   label="Start"
-   layout="topleft"
-   left_delta="0"
-   name="start_btn"
-   top_delta="30"
-   width="70">
-    <button.commit_callback
-		function="TexFetchDebugger.Start" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Reset"
-   layout="topleft"
-   left_pad="7"
-   name="clear_btn"
-   top_delta="0"
-   width="70">
-    <button.commit_callback
-		function="TexFetchDebugger.Clear" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Close"
-   layout="topleft"
-   left_pad="7"
-   name="close_btn"
-   top_delta="0"
-   width="70">
-    <button.commit_callback
-		function="TexFetchDebugger.Close" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Cache Read"
-   layout="topleft"
-   left="10"
-   name="cacheread_btn"
-   top_delta="30"
-   width="80">
-    <button.commit_callback
-		function="TexFetchDebugger.CacheRead" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Cache Write"
-   layout="topleft"
-   left_pad="7"
-   name="cachewrite_btn"
-   top_delta="0"
-   width="80">
-    <button.commit_callback
-		function="TexFetchDebugger.CacheWrite" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="HTTP"
-   layout="topleft"
-   left_pad="7"
-   name="http_btn"
-   top_delta="0"
-   width="70">
-    <button.commit_callback
-		function="TexFetchDebugger.HTTPLoad" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Decode"
-   layout="topleft"
-   left_pad="7"
-   name="decode_btn"
-   top_delta="0"
-   width="70">
-    <button.commit_callback
-		function="TexFetchDebugger.Decode" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="GL Texture"
-   layout="topleft"
-   left_pad="7"
-   name="gl_btn"
-   top_delta="0"
-   width="70">
-    <button.commit_callback
-		function="TexFetchDebugger.GLTexture" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Refetch Vis Cache"
-   layout="topleft"
-   left="10"
-   name="refetchviscache_btn"
-   top_delta="30"
-   width="120">
-    <button.commit_callback
-		function="TexFetchDebugger.RefetchVisCache" />
-  </button>
-  <button
-   follows="left|top"
-   height="20"
-   label="Refetch Vis HTTP"
-   layout="topleft"
-   left_pad="7"
-   name="refetchvishttp_btn"
-   top_delta="0"
-   width="120">
-    <button.commit_callback
-		function="TexFetchDebugger.RefetchVisHTTP" />
-  </button>
-</floater>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ height="550"
+ layout="topleft"
+ name="TexFetchDebugger"
+ help_topic="texfetchdebugger"
+ title="Texture Fetching Debugger"
+ width="540">
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left="10"
+   name="total_num_fetched_label"
+   top="30"
+   width="400">
+    1, Total number of fetched textures: [NUM]
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_num_fetching_requests_label"
+   top_delta="25"
+   width="400">
+    2, Total number of fetching requests: [NUM]
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_num_cache_hits_label"
+   top_delta="25"
+   width="400">
+    3, Total number of cache hits: [NUM]
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_num_visible_tex_label"
+   top_delta="25"
+   width="400">
+    4, Total number of visible textures: [NUM]
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_num_visible_tex_fetch_req_label"
+   top_delta="25"
+   width="450">
+    5, Total number of visible texture fetching requests: [NUM]
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_fetched_data_label"
+   top_delta="25"
+   width="530">
+    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_fetched_vis_data_label"
+   top_delta="25"
+   width="480">
+    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_fetched_rendered_data_label"
+   top_delta="25"
+   width="530">
+    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_time_cache_read_label"
+   top_delta="25"
+   width="400">
+    9, Total time on cache readings: [TIME] seconds
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_time_cache_write_label"
+   top_delta="25"
+   width="400">
+    10, Total time on cache writings: [TIME] seconds
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_time_decode_label"
+   top_delta="25"
+   width="400">
+    11, Total time on decodings: [TIME] seconds
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_time_gl_label"
+   top_delta="25"
+   width="400">
+    12, Total time on gl texture creation: [TIME] seconds
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_time_http_label"
+   top_delta="25"
+   width="400">
+    13, Total time on HTTP fetching: [TIME] seconds
+  </text>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="25"
+   layout="topleft"
+   left_delta="0"
+   name="total_time_fetch_label"
+   top_delta="25"
+   width="400">
+    14, Total time on entire fetching: [TIME] seconds
+  </text>
+  <text
+  type="string"
+  length="1"
+  follows="left|top"
+  height="25"
+  layout="topleft"
+  left_delta="0"
+  name="total_time_refetch_vis_cache_label"
+  top_delta="25"
+  width="540">
+    15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+  </text>
+  <text
+  type="string"
+  length="1"
+  follows="left|top"
+  height="25"
+  layout="topleft"
+  left_delta="0"
+  name="total_time_refetch_vis_http_label"
+  top_delta="25"
+  width="540">
+    16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+  </text>
+  <spinner
+     decimal_digits="2"
+     follows="left|top"
+     height="20"
+     increment="0.01"
+     initial_value="1.0"
+     label="17, Ratio of Texel/Pixel:"
+     label_width="130"
+     layout="topleft"
+     left_delta="0"
+     max_val="10.0"
+     min_val="0.01"
+     name="texel_pixel_ratio"
+     top_delta="30"
+     width="200">
+    <spinner.commit_callback
+		function="TexFetchDebugger.ChangeTexelPixelRatio" />
+  </spinner>
+  <button
+   follows="left|top"
+   height="20"
+   label="Start"
+   layout="topleft"
+   left_delta="0"
+   name="start_btn"
+   top_delta="30"
+   width="70">
+    <button.commit_callback
+		function="TexFetchDebugger.Start" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Reset"
+   layout="topleft"
+   left_pad="7"
+   name="clear_btn"
+   top_delta="0"
+   width="70">
+    <button.commit_callback
+		function="TexFetchDebugger.Clear" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Close"
+   layout="topleft"
+   left_pad="7"
+   name="close_btn"
+   top_delta="0"
+   width="70">
+    <button.commit_callback
+		function="TexFetchDebugger.Close" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Cache Read"
+   layout="topleft"
+   left="10"
+   name="cacheread_btn"
+   top_delta="30"
+   width="80">
+    <button.commit_callback
+		function="TexFetchDebugger.CacheRead" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Cache Write"
+   layout="topleft"
+   left_pad="7"
+   name="cachewrite_btn"
+   top_delta="0"
+   width="80">
+    <button.commit_callback
+		function="TexFetchDebugger.CacheWrite" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="HTTP"
+   layout="topleft"
+   left_pad="7"
+   name="http_btn"
+   top_delta="0"
+   width="70">
+    <button.commit_callback
+		function="TexFetchDebugger.HTTPLoad" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Decode"
+   layout="topleft"
+   left_pad="7"
+   name="decode_btn"
+   top_delta="0"
+   width="70">
+    <button.commit_callback
+		function="TexFetchDebugger.Decode" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="GL Texture"
+   layout="topleft"
+   left_pad="7"
+   name="gl_btn"
+   top_delta="0"
+   width="70">
+    <button.commit_callback
+		function="TexFetchDebugger.GLTexture" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Refetch Vis Cache"
+   layout="topleft"
+   left="10"
+   name="refetchviscache_btn"
+   top_delta="30"
+   width="120">
+    <button.commit_callback
+		function="TexFetchDebugger.RefetchVisCache" />
+  </button>
+  <button
+   follows="left|top"
+   height="20"
+   label="Refetch Vis HTTP"
+   layout="topleft"
+   left_pad="7"
+   name="refetchvishttp_btn"
+   top_delta="0"
+   width="120">
+    <button.commit_callback
+		function="TexFetchDebugger.RefetchVisHTTP" />
+  </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_text_editor.xml b/indra/newview/skins/default/xui/en/menu_text_editor.xml
index fe8489166b927c9a490bf6b189b79a279797a27b..70b40dd89b4cd09aac8b503b2ae7d9bea7e4292e 100644
--- a/indra/newview/skins/default/xui/en/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/menu_text_editor.xml
@@ -1,6 +1,85 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu
  name="Text editor context menu">
+  <menu_item_call
+   label="(unknown)"
+   layout="topleft"
+   name="Suggestion 1">
+    <menu_item_call.on_click
+     function="SpellCheck.ReplaceWithSuggestion"
+     parameter="0" />
+    <menu_item_call.on_visible
+     function="SpellCheck.VisibleSuggestion"
+     parameter="0" />
+  </menu_item_call>
+  <menu_item_call
+   label="(unknown)"
+   layout="topleft"
+   name="Suggestion 2">
+    <menu_item_call.on_click
+     function="SpellCheck.ReplaceWithSuggestion"
+     parameter="1" />
+    <menu_item_call.on_visible
+     function="SpellCheck.VisibleSuggestion"
+     parameter="1" />
+  </menu_item_call>
+  <menu_item_call
+   label="(unknown)"
+   layout="topleft"
+   name="Suggestion 3">
+    <menu_item_call.on_click
+     function="SpellCheck.ReplaceWithSuggestion"
+     parameter="2" />
+    <menu_item_call.on_visible
+     function="SpellCheck.VisibleSuggestion"
+     parameter="2" />
+  </menu_item_call>
+  <menu_item_call
+   label="(unknown)"
+   layout="topleft"
+   name="Suggestion 4">
+    <menu_item_call.on_click
+     function="SpellCheck.ReplaceWithSuggestion"
+     parameter="3" />
+    <menu_item_call.on_visible
+     function="SpellCheck.VisibleSuggestion"
+     parameter="3" />
+  </menu_item_call>
+  <menu_item_call
+   label="(unknown)"
+   layout="topleft"
+   name="Suggestion 5">
+    <menu_item_call.on_click
+     function="SpellCheck.ReplaceWithSuggestion"
+     parameter="4" />
+    <menu_item_call.on_visible
+     function="SpellCheck.VisibleSuggestion"
+     parameter="4" />
+  </menu_item_call>
+  <menu_item_separator
+   layout="topleft"
+   name="Suggestion Separator" />
+  <menu_item_call
+   label="Add to Dictionary"
+   layout="topleft"
+   name="Add to Dictionary">
+    <menu_item_call.on_click
+     function="SpellCheck.AddToDictionary" />
+    <menu_item_call.on_enable
+     function="SpellCheck.EnableAddToDictionary" />
+  </menu_item_call>
+  <menu_item_call
+   label="Add to Ignore"
+   layout="topleft"
+   name="Add to Ignore">
+    <menu_item_call.on_click
+     function="SpellCheck.AddToIgnore" />
+    <menu_item_call.on_enable
+     function="SpellCheck.EnableAddToIgnore" />
+  </menu_item_call>
+  <menu_item_separator
+   layout="topleft"
+   name="Spellcheck Separator" />
   <menu_item_call
    label="Cut"
    layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index a6898c554fcb6a88654f18a8e13759ca1b51d807..6bcdc615c3b420dc3c7558e9c2b595f6048e27cd 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -193,6 +193,15 @@
            <menu_item_call.on_click
             function="View.ToggleUI" />
          </menu_item_call>
+         <menu_item_check
+         label="Show HUD Attachments"
+         name="Show HUD Attachments"
+         shortcut="alt|shift|H">
+           <menu_item_check.on_check
+            function="View.CheckHUDAttachments" />
+            <menu_item_check.on_click
+             function="View.ShowHUDAttachments" />
+         </menu_item_check>
 
         <menu_item_separator/>
 
@@ -291,6 +300,12 @@
               function="SideTray.PanelPeopleTab"
               parameter="nearby_panel" />
         </menu_item_call>
+        <menu_item_call
+         label="Block List"
+         name="Block List">
+            <menu_item_call.on_click
+              function="Communicate.BlockList" />
+        </menu_item_call>
     </menu>
     <menu
      create_jump_keys="true"
@@ -1373,15 +1388,6 @@
                 <menu_item_check.on_click
                  function="View.HighlightTransparent" />
             </menu_item_check>
-            <menu_item_check
-             label="Show HUD Attachments"
-             name="Show HUD Attachments"
-             shortcut="alt|shift|H">
-                <menu_item_check.on_check
-                 function="View.CheckHUDAttachments" />
-                <menu_item_check.on_click
-                 function="View.ShowHUDAttachments" />
-            </menu_item_check>
             <menu_item_check
              label="Show Mouselook Crosshairs"
              name="ShowCrosshairs">
@@ -3125,12 +3131,6 @@
                     <menu_item_call.on_click
                      function="Advanced.TestFemale" />
                 </menu_item_call>
-                <menu_item_call
-                 label="Toggle PG"
-                 name="Toggle PG">
-                    <menu_item_call.on_click
-                     function="Advanced.TogglePG" />
-                </menu_item_call>
                 <menu_item_check
                  label="Allow Select Avatar"
                  name="Allow Select Avatar">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a26c5bb3449969e023b538cf835966dcb7f49593..91b4d38e9718a3a0a1ad6781ac6e93c8a21d14a5 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2358,6 +2358,93 @@ Would you be my friend?
     </form>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   label="Add Auto-Replace List"
+   name="AddAutoReplaceList"
+   type="alertmodal">
+    <tag>addlist</tag>
+    Name for the new list:
+    <tag>confirm</tag>
+    <form name="form">
+      <input name="listname" type="text"/>
+      <button
+       default="true"
+       index="0"
+       name="SetName"
+       text="OK"/>
+    </form>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   label="Rename Auto-Replace List"
+   name="RenameAutoReplaceList"
+   type="alertmodal">
+    The name '[DUPNAME]' is in use
+    Enter a new unique name:
+    <tag>confirm</tag>
+    <form name="form">
+      <input name="listname" type="text"/>
+      <button
+       default="false"
+       index="0"
+       name="ReplaceList"
+       text="Replace Current List"/>
+      <button
+       default="true"
+       index="1"
+       name="SetName"
+       text="Use New Name"/>
+    </form>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="InvalidAutoReplaceEntry"
+   type="alertmodal">
+    The keyword must be a single word, and the replacement may not be empty.
+    <tag>fail</tag>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="InvalidAutoReplaceList"
+   type="alertmodal">
+    That replacement list is not valid.
+    <tag>fail</tag>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="SpellingDictImportRequired"
+   type="alertmodal">
+    You must specify a file, a name, and a language.
+    <tag>fail</tag>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="SpellingDictIsSecondary"
+   type="alertmodal">
+The dictionary [DIC_NAME] does not appear to have an "aff" file; this means that it is a "secondary" dictionary.
+It can be used as an additional dictionary, but not as your Main dictionary.
+
+See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+    <tag>confirm</tag>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="SpellingDictImportFailed"
+   type="alertmodal">
+    Unable to copy
+    [FROM_NAME]
+    to
+    [TO_NAME]
+    <tag>fail</tag>
+  </notification>
+
   <notification
  icon="alertmodal.tga"
  label="Save Outfit"
@@ -4089,9 +4176,7 @@ Are you sure you want to change the Estate Covenant?
    name="RegionEntryAccessBlocked"
    type="alertmodal">
    <tag>fail</tag>
-You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
     <usetemplate
      name="okbutton"
      yestext="OK"/>
@@ -4099,13 +4184,11 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
 
   <notification
    icon="alertmodal.tga"
-   name="RegionEntryAccessBlocked_KB"
+   name="RegionEntryAccessBlocked_AdultsOnlyContent"
    type="alertmodal">
    <tag>fail</tag>
     <tag>confirm</tag>
-You are not allowed in that region due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+    The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
     <url option="0" name="url">
 		http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
     </url>
@@ -4113,7 +4196,7 @@ Go to the Knowledge Base for more information about maturity Ratings?
      name="okcancelignore"
      yestext="Go to Knowledge Base"
 	 notext="Close"
-	 ignoretext="I can&apos;t enter this Region, due to restrictions of the maturity Rating"/>
+	 ignoretext="Region crossing: The region you&apos;re trying to visit contains content which is accessible to adults only."/>
   </notification>
 
   <notification
@@ -4121,47 +4204,156 @@ Go to the Knowledge Base for more information about maturity Ratings?
    name="RegionEntryAccessBlocked_Notify"
    type="notifytip">
    <tag>fail</tag>
-You are not allowed in that region due to your maturity Rating.
+The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+  </notification>
+
+  <notification
+   icon="notifytip.tga"
+   name="RegionEntryAccessBlocked_NotifyAdultsOnly"
+   type="notifytip">
+    <tag>fail</tag>
+    The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
   </notification>
 
   <notification
    icon="alertmodal.tga"
    name="RegionEntryAccessBlocked_Change"
    type="alertmodal">
-   <tag>fail</tag>
+    <tag>fail</tag>
     <tag>confirm</tag>
-You are not allowed in that Region due to your maturity Rating preference.
-
-To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me &gt; Preferences &gt; General.
-	 <form name="form">
+The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel. After your preferences are changed, you may attempt to enter the region again.
+    <form name="form">
       <button
        index="0"
        name="OK"
-       text="Change Preference"/>
-      <button
+       text="Change preferences"/>
+      <button 
        default="true"
        index="1"
        name="Cancel"
-       text="Close"/>
-       <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/>
+       text="Cancel"/>
+      <ignore name="ignore" text="Region crossing: The region you&apos;re trying to visit contains content excluded by your preferences."/>
     </form>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="RegionEntryAccessBlocked_PreferencesOutOfSync"
+   type="alertmodal">
+    <tag>fail</tag>
+    We are having technical difficulties with your teleport because your preferences are out of sync with the server.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="TeleportEntryAccessBlocked"
+   type="alertmodal">
+    <tag>fail</tag>
+    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="TeleportEntryAccessBlocked_AdultsOnlyContent"
+   type="alertmodal">
+    <unique>
+      <context>REGIONMATURITY</context>
+    </unique>
+    <tag>fail</tag>
+    <tag>confirm</tag>
+    The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
+    <url option="0" name="url">
+      http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+    </url>
+    <usetemplate
+     name="okcancelignore"
+     yestext="Go to Knowledge Base"
+	 notext="Close"
+	 ignoretext="Teleport: The region you&apos;re trying to visit contains content which is accessible to adults only."/>
+  </notification>
+
   <notification
    icon="notifytip.tga"
-   name="PreferredMaturityChanged"
+   name="TeleportEntryAccessBlocked_Notify"
+   type="notifytip">
+    <unique>
+      <context>REGIONMATURITY</context>
+    </unique>
+    <tag>fail</tag>
+    The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+  </notification>
+
+  <notification
+   icon="notifytip.tga"
+   name="TeleportEntryAccessBlocked_NotifyAdultsOnly"
    type="notifytip">
-Your maturity Rating preference is now [RATING].
+    <unique>
+      <context>REGIONMATURITY</context>
+    </unique>
+    <tag>fail</tag>
+    The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
   </notification>
 
   <notification
    icon="alertmodal.tga"
-   name="LandClaimAccessBlocked"
+   name="TeleportEntryAccessBlocked_ChangeAndReTeleport"
    type="alertmodal">
-You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age.
+    <unique>
+      <context>REGIONMATURITY</context>
+    </unique>
+    <tag>fail</tag>
+    <tag>confirm</tag>
+    The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport.
+    <form name="form">
+      <button
+       index="0"
+       name="OK"
+       text="Change and continue"/>
+      <button
+       default="true"
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+      <ignore name="ignore" text="Teleport (restartable): The region you&apos;re trying to visit contains content excluded by your preferences."/>
+    </form>
+  </notification>
 
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
-  <tag>fail</tag>
+  <notification
+   icon="alertmodal.tga"
+   name="TeleportEntryAccessBlocked_Change"
+   type="alertmodal">
+    <unique>
+      <context>REGIONMATURITY</context>
+    </unique>
+    <tag>fail</tag>
+    <tag>confirm</tag>
+    The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel the teleport. After your preferences are changed, you will need to attempt the teleport again.
+    <form name="form">
+      <button
+       index="0"
+       name="OK"
+       text="Change preferences"/>
+      <button
+       default="true"
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+      <ignore name="ignore" text="Teleport (non-restartable): The region you&apos;re trying to visit contains content excluded by your preferences."/>
+    </form>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="TeleportEntryAccessBlocked_PreferencesOutOfSync"
+   type="alertmodal">
+    <tag>fail</tag>
+    We are having technical difficulties with your teleport because your preferences are out of sync with the server.
     <usetemplate
      name="okbutton"
      yestext="OK"/>
@@ -4169,12 +4361,43 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
 
   <notification
    icon="alertmodal.tga"
-   name="LandClaimAccessBlocked_KB"
+   name="PreferredMaturityChanged"
    type="alertmodal">
-You cannot claim this land due to your maturity Rating.
+You won't receive any more notifications that you're about to visit a region with [RATING] content.  You may change your content preferences in the future by using Me &gt; Preferences &gt; General from the menu bar.
+  <tag>confirm</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
 
-Go to the Knowledge Base for more information about maturity Ratings?
-  <tag>fail</tag>
+  <notification
+   icon="alertmodal.tga"
+   name="MaturityChangeError"
+   type="alertmodal">
+    We were unable to change your preferences to view [PREFERRED_MATURITY] content at this time.  Your preferences have been reset to view [ACTUAL_MATURITY] content.  You may attempt to change your preferences again by using Me &gt; Preferences &gt; General from the menu bar.
+    <tag>confirm</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="LandClaimAccessBlocked"
+   type="alertmodal">
+    The land you're trying to claim has a maturity rating exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+    <tag>fail</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="LandClaimAccessBlocked_AdultsOnlyContent"
+   type="alertmodal">
+    Only adults can claim this land.
+    <tag>fail</tag>
     <tag>confirm</tag>
     <url option="0" name="url">
 		http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
@@ -4183,41 +4406,52 @@ Go to the Knowledge Base for more information about maturity Ratings?
      name="okcancelignore"
      yestext="Go to Knowledge Base"
 	 notext="Close"
-	 ignoretext="I can&apos;t claim this Land, due to restrictions of the maturity Rating"/>
+	 ignoretext="Only adults can claim this land."/>
   </notification>
 
   <notification
    icon="notifytip.tga"
    name="LandClaimAccessBlocked_Notify"
    type="notifytip">
-You cannot claim this land due to your maturity Rating.
-  <tag>fail</tag>
+    The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+    <tag>fail</tag>
+  </notification>
+
+  <notification
+   icon="notifytip.tga"
+   name="LandClaimAccessBlocked_NotifyAdultsOnly"
+   type="notifytip">
+    <tag>fail</tag>
+    The land you're trying to claim contains [REGIONMATURITY] content, which is accessible to adults only.
   </notification>
 
   <notification
    icon="alertmodal.tga"
    name="LandClaimAccessBlocked_Change"
    type="alertmodal">
-You cannot claim this land due to your maturity Rating preference.
-
-You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+    The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try claiming the land again.
     <tag>fail</tag>
     <tag>confirm</tag>
-    <usetemplate
-     name="okcancelignore"
-     yestext="Change Preference"
-	 notext="Close"
-	 ignoretext="My chosen Rating preference prevents me from claiming Land"/>
+    <form name="form">
+      <button
+       index="0"
+       name="OK"
+       text="Change preferences"/>
+      <button
+       default="true"
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+      <ignore name="ignore" text="The land you&apos;re trying to claim contains content excluded by your preferences."/>
+    </form>
   </notification>
 
   <notification
    icon="alertmodal.tga"
    name="LandBuyAccessBlocked"
    type="alertmodal">
-You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
-  <tag>fail</tag>
+    The land you're trying to buy has a maturity rating exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+    <tag>fail</tag>
     <usetemplate
      name="okbutton"
      yestext="OK"/>
@@ -4225,11 +4459,9 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
 
   <notification
    icon="alertmodal.tga"
-   name="LandBuyAccessBlocked_KB"
+   name="LandBuyAccessBlocked_AdultsOnlyContent"
    type="alertmodal">
-You cannot buy this land due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+    Only adults can buy this land.
     <tag>confirm</tag>
   <tag>fail</tag>
     <url option="0" name="url">
@@ -4239,31 +4471,44 @@ Go to the Knowledge Base for more information about maturity Ratings?
      name="okcancelignore"
      yestext="Go to Knowledge Base"
 	 notext="Close"
-	 ignoretext="I can&apos;t buy this Land, due to restrictions of the maturity Rating"/>
+	 ignoretext="Only adults can buy this land."/>
   </notification>
 
   <notification
    icon="notifytip.tga"
    name="LandBuyAccessBlocked_Notify"
    type="notifytip">
-You cannot buy this land due to your maturity Rating.
-  <tag>fail</tag>
+    The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+    <tag>fail</tag>
+  </notification>
+
+  <notification
+   icon="notifytip.tga"
+   name="LandBuyAccessBlocked_NotifyAdultsOnly"
+   type="notifytip">
+    <tag>fail</tag>
+    The land you're trying to buy contains [REGIONMATURITY] content, which is accessible to adults only.
   </notification>
 
   <notification
    icon="alertmodal.tga"
    name="LandBuyAccessBlocked_Change"
    type="alertmodal">
-You cannot buy this land due to your maturity Rating preference.
-
-You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+    The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try buying the land again.
     <tag>confirm</tag>
     <tag>fail</tag>
-    <usetemplate
-     name="okcancelignore"
-     yestext="Change Preference"
-	 notext="Close"
-	 ignoretext="My chosen Rating preference prevents me from buying Land"/>
+    <form name="form">
+      <button
+       index="0"
+       name="OK"
+       text="Change preferences"/>
+      <button
+       default="true"
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+      <ignore name="ignore" text="The land you&apos;re trying to buy contains content excluded by your preferences."/>
+    </form>
   </notification>
 
 	<notification
@@ -4418,10 +4663,11 @@ Type a short announcement which will be sent to everyone in this region.
    label="Changed Region Maturity"
    name="RegionMaturityChange"
    type="alertmodal">
-The maturity rating for this region has been updated.
-It may take some time for the change to be reflected on the map.
-
-To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification.
+The maturity rating for this region has been changed.
+It may take some time for this change to be reflected on the map.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
   </notification>
 
   <notification
@@ -5127,20 +5373,20 @@ Would you like to automatically wear the clothing you are about to create?
    icon="alertmodal.tga"
    name="NotAgeVerified"
    type="alertmodal">
-   <tag>fail</tag>
-To access adult content and areas in Second Life you must be at least 18 years old. Please visit our age verification page to confirm you are over 18. 
-Note this will launch your web browser.
-
-[_URL]
-    <tag>confirm</tag>
-    <url option="0" name="url">
-	    https://secondlife.com/my/account/verification.php
-    </url>
+    The location you're trying to visit is restricted to residents age 18 and over.
+    <tag>fail</tag>
     <usetemplate
-     ignoretext="I have not verified my age"
-     name="okcancelignore"
-     notext="Cancel"
-     yestext="Go to Age Verification"/>
+     ignoretext="I am not old enough to visit age restricted areas."
+     name="okignore"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="notifytip.tga"
+   name="NotAgeVerified_Notify"
+   type="notifytip">
+    Location restricted to age 18 and over.
+    <tag>fail</tag>
   </notification>
 
   <notification
@@ -5287,7 +5533,7 @@ Terrain.raw downloaded
    icon="notifytip.tga"
    name="GestureMissing"
    type="notifytip">
-Hmm. Gesture [NAME] is missing from the database.
+Gesture [NAME] is missing from the database.
   <tag>fail</tag>
   </notification>
 
@@ -5825,9 +6071,7 @@ You can only claim public land in the Region you&apos;re in.
    persist="true"
    type="notify">
    <tag>fail</tag>
-You aren&apos;t allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer.
-
-Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
+    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
   </notification>
 
   <notification
@@ -5859,11 +6103,11 @@ You do not have proper payment status to enter this region.
 
   <notification
 	icon="notify.tga"
-	name="MustGetAgeRgion"
+	name="MustGetAgeRegion"
    persist="true"
 	type="notify">
    <tag>fail</tag>
-You must be age-verified to enter this region.
+You must be age 18 or over to enter this region.
   </notification>
 
   <notification
@@ -5872,7 +6116,7 @@ You must be age-verified to enter this region.
    persist="true"
 	type="notify">
    <tag>fail</tag>
-You must be age-verified to enter this parcel.
+    You must be age 18 or over to enter this parcel.
   </notification>
 
   <notification
@@ -6147,7 +6391,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    type="offer">
 [NAME_SLURL] has offered to teleport you to their location:
 
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]”
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
     <tag>confirm</tag>
     <form name="form">
       <button
@@ -6161,6 +6406,42 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
     </form>
   </notification>
 
+  <notification
+   icon="notify.tga"
+   name="TeleportOffered_MaturityExceeded"
+   type="offer">
+[NAME_SLURL] has offered to teleport you to their location:
+
+“[MESSAGE]”
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+This region contains [REGION_CONTENT_MATURITY] content, but your current preferences are set to exclude [REGION_CONTENT_MATURITY] content.  We can change your preferences and continue with the teleport, or you can cancel this teleport.
+    <tag>confirm</tag>
+    <form name="form">
+      <button
+       index="0"
+       name="Teleport"
+       text="Change and Continue"/>
+      <button
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+    </form>
+  </notification>
+
+  <notification
+   icon="notify.tga"
+   name="TeleportOffered_MaturityBlocked"
+   type="notifytip">
+[NAME_SLURL] has offered to teleport you to their location:
+
+“[MESSAGE]”
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+However, this region contains content accessible to adults only.
+    <tag>fail</tag>
+  </notification>
+
   <notification
    icon="notify.tga"
    name="TeleportOfferSent"
@@ -7195,6 +7476,18 @@ You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] second
 You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="LivePreviewUnavailable"
+   type="alert">
+   
+We cannot display a preview of this texture because it is no-copy and/or no-transfer.
+  <usetemplate
+    ignoretext="Warn me that Live Preview mode is not available for no-copy and/or no-transfer textures"
+    name="okignore"
+    yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="ConfirmLeaveCall"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 0faa1598b1b932cbaa7d28dbbe8756bc6714c299..553c112e6fc7025f6f24071d4c8a534b81f891a9 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -134,6 +134,7 @@
          top_pad="2"
          max_length="1023"
          name="pick_desc"
+         spellcheck="true"
          text_color="black"
          word_wrap="true" />
         <text
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 607e1bb2135ba621643a3df3037e316c457f45b2..6d5fb51e85892d86d1836e4a89c8681629459821 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -141,6 +141,7 @@ Maximum 200 per group daily
          max_length_bytes="63"
          name="create_subject"
          prevalidate_callback="ascii"
+         spellcheck="true"
          width="218" />
         <text
          follows="left|top"
@@ -161,6 +162,7 @@ Maximum 200 per group daily
          left_pad="3"
          max_length="511"
          name="create_message"
+         spellcheck="true"
          top_delta="0"
          width="218"
          word_wrap="true" />
@@ -309,6 +311,7 @@ Maximum 200 per group daily
          left_pad="3"
          max_length_bytes="63"
          name="view_subject"
+         spellcheck="true"
          top_delta="-1"
          visible="false"
          width="200" />
@@ -333,6 +336,7 @@ Maximum 200 per group daily
          right="-1"
          max_length="511"
          name="view_message"
+         spellcheck="true"
          top_delta="-40"
          width="313"
          word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 21c627cdfb82407f50b9c27be99559f1d9cf74fc..6bc9c48729dbb6189dc2f82fed66363668d3c10c 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -19,6 +19,7 @@
      left="0"
      max_length_bytes="1023"
      name="chat_box"
+     spellcheck="true"
      text_pad_left="5"
      text_pad_right="25"
      tool_tip="Press Enter to say, Ctrl+Enter to shout"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index caf7fc85f569d5d50a1cf40eeb4b98244885afd0..27193a984f0087e81099223de5f4736f8812e43a 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -207,13 +207,36 @@
   <button
    follows="left|top"
    height="23"
-   label="Chat Translation Settings"
+   label="Translation..."
    layout="topleft"
    left="30"
    name="ok_btn"
-   top="-40"
+   top="-50"
    width="170">
    <button.commit_callback
     function="Pref.TranslationSettings" />
   </button>
-</panel>
\ No newline at end of file
+  <button
+   follows="top|left"
+   height="23"
+   layout="topleft"
+   top_pad="-23"
+   left_pad="5"
+   name="autoreplace_showgui"
+   commit_callback.function="Pref.AutoReplace"
+   label="Auto-Replace..."
+   width="150">
+  </button>
+  <button
+   follows="top|left"
+   height="23"
+   layout="topleft"
+   top_pad="-23"
+   left_pad="5"
+   name="spellcheck_showgui"
+   commit_callback.function="Pref.SpellChecker"
+   label="Spell Checking..."
+   width="150">
+  </button>
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index bfd796a62bd91da5ac00c702ae97171ac7f71e14..76a82212ae95e1c5fd131a1ba5979f93f4aa1ec0 100644
--- a/indra/newview/skins/default/xui/en/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -149,11 +149,11 @@
     <check_box
      follows="top|left"
      height="16"
-     label="Have been age-verified"
+     label="Are age 18 or older"
      layout="topleft"
      left_delta="0"
      name="limit_age_verified"
-     tool_tip="Residents must be age verified to access this estate. See the [SUPPORT_SITE] for more information."
+     tool_tip="Residents must be age 18 or older to access this estate. See the [SUPPORT_SITE] for more information."
      top_pad="2"
      width="278" />
 
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index 6ecb57b41d8da6bc45d16df29bc672080f1618ed..14bd34948041110ae0017d92c0a2552cfea123f0 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -48,7 +48,7 @@
                       height="300"
                       width="330" />
              </layout_panel>
-			 <layout_panel
+			    <layout_panel
                  width="330"
                  layout="topleft"
                  auto_resize="false"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 866ea296c3a33ed675c8b0e329931060ebd7b857..6dd80dc11ae6126e6a57fdff3486c754ad3f6562 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -441,6 +441,7 @@ Please try logging in again in a minute.</string>
 	<string name="load_files">Load Files</string>
 	<string name="choose_the_directory">Choose Directory</string>
 	<string name="script_files">Scripts</string>
+	<string name="dictionary_files">Dictionaries</string>
 
   <!-- LSL Usage Hover Tips -->
   <!-- NOTE: For now these are set as translate="false", until DEV-40761 is implemented (to internationalize the rest of tooltips in the same window).
@@ -3758,4 +3759,9 @@ Try enclosing path to the editor with double quotes.
   <string name="snapshot_quality_high">High</string>
   <string name="snapshot_quality_very_high">Very High</string>
 
+  <string name="TeleportMaturityExceeded">The Resident cannot visit this region.</string>
+
+  <!-- Spell check settings floater -->
+  <string name="UserDictionary">[User]</string>
+  
   </strings>
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
index dce6b8dd6d6182fd5244c8778add4b624b63221d..fdf41991cd56f61c244a818459d8d3bfef7e6c8c 100644
--- a/indra/newview/skins/default/xui/en/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -45,6 +45,9 @@ Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
 		<message name="no_inventory_host">
 			The inventory system is currently unavailable.
 		</message>
+    <message name="MustGetAgeRegion">
+      You must be age 18 or over to enter this region.
+    </message>
 	</message_set>
 	<message_set name="progress">
 		<message name="sending_dest">
@@ -80,5 +83,8 @@ Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
 		<message name="requesting">
 			Requesting Teleport...
 		</message>
-	</message_set>
+    <message name="pending">
+      Pending Teleport...
+    </message>
+  </message_set>
 </teleport_messages>
diff --git a/indra/newview/skins/default/xui/es/floater_model_wizard.xml b/indra/newview/skins/default/xui/es/floater_model_wizard.xml
deleted file mode 100644
index 5bd6b5e0e55731176d5373ce0390a43d0f6bf555..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/es/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="CARGAR ASISTENTE DE MODELO">
-	<button label="5. Subir" name="upload_btn"/>
-	<button label="4. Revisar" name="review_btn"/>
-	<button label="3. Física" name="physics_btn"/>
-	<button label="2. Optimizar" name="optimize_btn"/>
-	<button label="1. Seleccionar archivo" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Elige el archivo de modelo
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Usuarios avanzados: si tienes experiencia con las herramientas de creación de contenidos 3D, quizá te interese utilizar la función de subida avanzada.
-			</text>
-			<button label="Cambiar al modo Avanzado" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Elige el archivo de modelo que deseas subir
-			</text>
-			<button label="Examinar..." label_selected="Examinar..." name="browse"/>
-			<text name="Model types">
-				‎Second Life admite los archivos COLLADA (.dae)
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				ATENCIÓN:
-			</text>
-			<text name="warning_text">
-				No podrás completar el paso final de la subida de este modelo a los servidores de Second Life. [secondlife:///app/floater/learn_more Averigua cómo] configurar tu cuenta para subir modelos de malla.
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Optimizar el modelo
-			</text>
-		</panel>
-		<text name="optimize_description">
-			Hemos optimizado el rendimiento del modelo, pero puedes ajustarlo más si lo deseas.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Generar el nivel de detalle: Alto
-			</text>
-			<text name="medium_detail_text">
-				Generar el nivel de detalle: Medio
-			</text>
-			<text name="low_detail_text">
-				Generar el nivel de detalle: Bajo
-			</text>
-			<text name="lowest_detail_text">
-				Generar el nivel de detalle: Mínimo
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Recalcular la geometría" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Vista previa de geometría
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="LOD para ver en renderizado de prueba">
-				<combo_item name="high">
-					Detalle alto
-				</combo_item>
-				<combo_item name="medium">
-					Detalles medios
-				</combo_item>
-				<combo_item name="low">
-					Detalle bajo
-				</combo_item>
-				<combo_item name="lowest">
-					Detalles mínimos
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Ajustar la física
-			</text>
-		</panel>
-		<text name="physics_description">
-			Crearemos una forma para la apariencia exterior del modelo. Ajusta el nivel de detalle de la forma según se necesite para el propósito proyectado del modelo.
-		</text>
-		<panel name="physics_content">
-			<button label="Recalcular física" name="recalculate_physics_btn"/>
-			<button label="Recalculando..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Prueba de física
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="LOD para ver en renderizado de prueba">
-				<combo_item name="high">
-					Detalle alto
-				</combo_item>
-				<combo_item name="medium">
-					Detalles medios
-				</combo_item>
-				<combo_item name="low">
-					Detalle bajo
-				</combo_item>
-				<combo_item name="lowest">
-					Detalles mínimos
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Revisar
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Impacto en la parcela/región: [EQUIV] equivalentes en prim
-			</text>
-			<text name="review_fee">
-				Cargaremos en tu cuenta el precio de subida de L$ [FEE].
-			</text>
-			<text name="review_confirmation">
-				Al pulsar en el botón de subida, confirmas que posees los derechos necesarios sobre el material que contiene el modelo.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Subida finalizada
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Se ha subido tu modelo.
-		</text>
-		<text name="inventory_text">
-			Puedes buscar la carpeta Objetos en tu inventario.
-		</text>
-		<text name="charged_fee">
-			Se han cargado [FEE] L$ en tu cuenta.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Atrás" name="back"/>
-	<button label="Siguiente &gt;&gt;" name="next"/>
-	<button label="Calcular pesos y precio &gt;&gt;" name="calculate"/>
-	<button label="Calculando..." name="calculating"/>
-	<button label="Subir" name="upload" tool_tip="Cargar al simulador"/>
-	<button label="Cancelar" name="cancel"/>
-	<button label="Cerrar" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		Inactivo
-	</string>
-	<string name="status_parse_error">
-		Problema de análisis de DAE - consulta los datos en el registro.
-	</string>
-	<string name="status_reading_file">
-		Cargando...
-	</string>
-	<string name="status_generating_meshes">
-		Generando redes...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Error: El número de intersección es superior a 65534. Cancelado.
-	</string>
-	<string name="bad_element">
-		Error: el elemento no es válido
-	</string>
-	<string name="high">
-		Alto
-	</string>
-	<string name="medium">
-		Media
-	</string>
-	<string name="low">
-		Bajo
-	</string>
-	<string name="lowest">
-		Mínimo
-	</string>
-	<string name="mesh_status_good">
-		Factúralo.
-	</string>
-	<string name="mesh_status_na">
-		N/A
-	</string>
-	<string name="mesh_status_none">
-		Ninguno
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Los niveles de detalle poseen un número distinto de caras a las que se pueden aplicar texturas.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Los niveles de detalle poseen un número distinto de ejemplos de red.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		El nivel de detalle posee demasiadas intersecciones.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Falta un nivel de detalle requerido.
-	</string>
-	<string name="layer_all">
-		Todo
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
index a3b50351ae44dc4d0a07eec01b0f8e3016c48e10..0f272891c73324de9ef82af06bb1dd21f625c4a6 100644
--- a/indra/newview/skins/default/xui/fr/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
@@ -214,7 +214,7 @@
 			</panel>
 		</tab_container>
 		<panel name="weights_and_warning_panel">
-			<button label="Calculer les poids et les frais." name="calculate_btn" tool_tip="Calculer les poids et les frais."/>
+			<button label="Calculer les poids et les frais" name="calculate_btn" tool_tip="Calculer les poids et les frais."/>
 			<button label="Annuler" name="cancel_btn"/>
 			<button label="Charger le modèle" name="ok_btn" tool_tip="Charger dans le simulateur"/>
 			<button label="Effacer les paramètres et réinitialiser le formulaire" name="reset_btn"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml b/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
deleted file mode 100644
index 128b9d6fa40af3486a149e85fde5299618f16eea..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="ASSISTANT DE CHARGEMENT DE MODÈLE">
-	<button label="5. Chargement" name="upload_btn"/>
-	<button label="4. Vérification" name="review_btn"/>
-	<button label="3. Propriétés physiques" name="physics_btn"/>
-	<button label="2. Optimisation" name="optimize_btn"/>
-	<button label="1. Sélection du fichier" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Choisir un fichier de modèle
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Utilisateurs expérimentés : si vous êtes habitué à utiliser des outils de création de contenu en 3D, l&apos;outil de chargement avancé est mis à votre disposition.
-			</text>
-			<button label="Passer à Avancé" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Choisir un fichier de modèle à charger
-			</text>
-			<button label="Parcourir..." label_selected="Parcourir..." name="browse"/>
-			<text name="Model types">
-				Second Life prend en charge les fichiers COLLADA (.dae).
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				AVERTISSEMENT :
-			</text>
-			<text name="warning_text">
-				Vous ne pourrez pas effectuer l&apos;étape de chargement finale du modèle sur les serveurs Second Life. [secondlife:///app/floater/learn_more Découvrez comment] configurer votre compte pour le chargement de modèles de maillage.
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Optimiser le modèle
-			</text>
-		</panel>
-		<text name="optimize_description">
-			Le modèle a été optimisé en termes de performances. Vous pouvez l&apos;ajuster si vous le souhaitez.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Générer le niveau de détail : Élevé
-			</text>
-			<text name="medium_detail_text">
-				Générer le niveau de détail : Moyen
-			</text>
-			<text name="low_detail_text">
-				Générer le niveau de détail : Faible
-			</text>
-			<text name="lowest_detail_text">
-				Générer le niveau de détail : Le plus faible
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Recalcul géométrique" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Aperçu de la géométrie
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="Niveau de détail à afficher en rendu d&apos;aperçu.">
-				<combo_item name="high">
-					Niveau de détail élevé
-				</combo_item>
-				<combo_item name="medium">
-					Niveau de détail moyen
-				</combo_item>
-				<combo_item name="low">
-					Niveau de détail faible
-				</combo_item>
-				<combo_item name="lowest">
-					Niveau de détail le plus faible
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Ajuster les propriétés physiques
-			</text>
-		</panel>
-		<text name="physics_description">
-			Une forme va être créée pour l&apos;enveloppe externe du modèle. Ajustez le niveau de détail de la forme en fonction de l&apos;objectif souhaité pour votre modèle.
-		</text>
-		<panel name="physics_content">
-			<button label="Recalcul physique" name="recalculate_physics_btn"/>
-			<button label="Recalcul en cours..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Aperçu des propriétés physiques
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="Niveau de détail à afficher en rendu d&apos;aperçu.">
-				<combo_item name="high">
-					Niveau de détail élevé
-				</combo_item>
-				<combo_item name="medium">
-					Niveau de détail moyen
-				</combo_item>
-				<combo_item name="low">
-					Niveau de détail faible
-				</combo_item>
-				<combo_item name="lowest">
-					Niveau de détail le plus faible
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Vérification
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Impact sur la parcelle/région : équivalent à [EQUIV] prims
-			</text>
-			<text name="review_fee">
-				Votre compte sera débité de [FEE] L$ de frais de chargement.
-			</text>
-			<text name="review_confirmation">
-				En cliquant sur le bouton de chargement, vous confirmez que vous disposez des droits appropriés sur le contenu du modèle.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Chargement terminé
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Votre modèle a été chargé.
-		</text>
-		<text name="inventory_text">
-			Vous le trouverez dans le dossier Objets de votre inventaire.
-		</text>
-		<text name="charged_fee">
-			Votre compte a été débité de [FEE] L$.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Préc." name="back"/>
-	<button label="Suiv. &gt;&gt;" name="next"/>
-	<button label="Calculer les poids et les frais &gt;&gt;" name="calculate"/>
-	<button label="Calcul en cours..." name="calculating"/>
-	<button label="Charger" name="upload" tool_tip="Charger dans le simulateur."/>
-	<button label="Annuler" name="cancel"/>
-	<button label="Fermer" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		Inactif
-	</string>
-	<string name="status_parse_error">
-		Problème d&apos;analyse de fichier .dae ; reportez-vous au journal pour plus de détails.
-	</string>
-	<string name="status_reading_file">
-		Chargement...
-	</string>
-	<string name="status_generating_meshes">
-		Génération des maillages...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Erreur : valeur de sommet supérieure à 65534. Opération abandonnée.
-	</string>
-	<string name="bad_element">
-		Erreur : élément non valide
-	</string>
-	<string name="high">
-		Élevé
-	</string>
-	<string name="medium">
-		Moyen
-	</string>
-	<string name="low">
-		Faible
-	</string>
-	<string name="lowest">
-		Le plus faible
-	</string>
-	<string name="mesh_status_good">
-		Bon à publier !
-	</string>
-	<string name="mesh_status_na">
-		N/A
-	</string>
-	<string name="mesh_status_none">
-		Aucun
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Un nombre différent de faces d&apos;application de texture est associé aux niveaux de détail.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Un nombre différent d&apos;instances de maillage est associé aux niveaux de détail.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		Trop de sommets pour le niveau de détail.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Niveau de détail requis manquant.
-	</string>
-	<string name="layer_all">
-		Tout
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_model_wizard.xml b/indra/newview/skins/default/xui/it/floater_model_wizard.xml
deleted file mode 100644
index ab5fdb29e4a36deb6a150e80588946c6675b0ee7..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/it/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="PROCEDURA GUIDATA CARICA MODELLO">
-	<button label="5. Carica sul server" name="upload_btn"/>
-	<button label="4. Rivedi" name="review_btn"/>
-	<button label="3. Fisica" name="physics_btn"/>
-	<button label="2. Ottimizza" name="optimize_btn"/>
-	<button label="1. Seleziona file" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Seleziona file modello
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Utenti avanzati: Gli utenti che hanno dimestichezza con gli strumenti di creazione 3D possono usare le opzioni di caricamento avanzate.
-			</text>
-			<button label="Passa a modalità avanzata" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Scegli il file del modello da caricare
-			</text>
-			<button label="Sfoglia..." label_selected="Sfoglia..." name="browse"/>
-			<text name="Model types">
-				Second Life supporta file COLLADA (.dae)
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				ATTENZIONE:
-			</text>
-			<text name="warning_text">
-				Non sarà possibile completare il passaggio finale per il caricamento finale di questo modello sui server di Second Life. [secondlife:///app/floater/learn_more Scopri come] impostare l&apos;account per il caricamento di modelli con reticolo.
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Ottimizza modello
-			</text>
-		</panel>
-		<text name="optimize_description">
-			Abbiamo ottimizzato il modello per migliorare le prestazioni. Se necessario, può essere regolato ulteriormente.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Genera livello di dettaglio: Alto
-			</text>
-			<text name="medium_detail_text">
-				Genera livello di dettaglio: Medio
-			</text>
-			<text name="low_detail_text">
-				Genera livello di dettaglio: Basso
-			</text>
-			<text name="lowest_detail_text">
-				Genera livello di dettaglio: Bassissimo
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Ricalcola geometria" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Anteprima geometria
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="Livello di dettaglio per anteprima rendering">
-				<combo_item name="high">
-					Molti dettagli
-				</combo_item>
-				<combo_item name="medium">
-					Dettagli medi
-				</combo_item>
-				<combo_item name="low">
-					Meno dettagli
-				</combo_item>
-				<combo_item name="lowest">
-					Dettaglio minimo
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Modifica fisica
-			</text>
-		</panel>
-		<text name="physics_description">
-			Verrà creata una forma per lo scafo esterno del modello. Regola il livello di dettaglio della forma in base al fine desiderato del modello.
-		</text>
-		<panel name="physics_content">
-			<button label="Ricalcola fisica" name="recalculate_physics_btn"/>
-			<button label="Ricalcolo in corso..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Anteprima fisica
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="Livello di dettaglio per anteprima rendering">
-				<combo_item name="high">
-					Molti dettagli
-				</combo_item>
-				<combo_item name="medium">
-					Dettagli medi
-				</combo_item>
-				<combo_item name="low">
-					Meno dettagli
-				</combo_item>
-				<combo_item name="lowest">
-					Dettaglio minimo
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Rivedi
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Impatto sul lotto o sulla regione: [EQUIV] prim equivalenti
-			</text>
-			<text name="review_fee">
-				All&apos;account verrà accreditata una tariffa di caricamento pari a L$ [FEE].
-			</text>
-			<text name="review_confirmation">
-				Facendo clic sul pulsante Carica, confermi di possedere i diritti relativi ai materiali contenuti nel modello.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Caricamento completato
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Il modello è stato caricato.
-		</text>
-		<text name="inventory_text">
-			Puoi trovarlo nella cartella Oggetti nel tuo inventario.
-		</text>
-		<text name="charged_fee">
-			La somma di L$ [FEE] è stata addebitata sul tuo account.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Indietro" name="back"/>
-	<button label="Avanti &gt;&gt;" name="next"/>
-	<button label="Calcolare pesi e tariffa &gt;&gt;" name="calculate"/>
-	<button label="Calcolo in corso..." name="calculating"/>
-	<button label="Carica" name="upload" tool_tip="Carica al simulatore"/>
-	<button label="Annulla" name="cancel"/>
-	<button label="Chiudi" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		Pausa
-	</string>
-	<string name="status_parse_error">
-		Problema nell&apos;elaborazione DAE - vedi il registro per informazioni al riguardo.
-	</string>
-	<string name="status_reading_file">
-		Caricamento in corso...
-	</string>
-	<string name="status_generating_meshes">
-		Generazione reticoli...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Errore: numero di vertici maggiore di 65534, annullato.
-	</string>
-	<string name="bad_element">
-		Errore: elemento non valido
-	</string>
-	<string name="high">
-		Alto
-	</string>
-	<string name="medium">
-		Medio
-	</string>
-	<string name="low">
-		Basso
-	</string>
-	<string name="lowest">
-		Bassissimo
-	</string>
-	<string name="mesh_status_good">
-		Invia!
-	</string>
-	<string name="mesh_status_na">
-		N/D
-	</string>
-	<string name="mesh_status_none">
-		Nessuno
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Ai vari livelli del dettaglio corrispondono numeri diversi di faccette con texture.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Ai vari livelli del dettaglio corrispondono numeri diversi istanze di reticoli.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		Troppi vertici per il livello di dettaglio.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Livello di dettaglio minimo mancante.
-	</string>
-	<string name="layer_all">
-		Tutto
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml b/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
deleted file mode 100644
index 746bd8553c8f3b6b8a0b0806a26274d7d963edcc..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="モデルウィザードをアップロード">
-	<button label="5. アップロード" name="upload_btn"/>
-	<button label="4. 確認" name="review_btn"/>
-	<button label="3. 物理効果" name="physics_btn"/>
-	<button label="2. 最適化" name="optimize_btn"/>
-	<button label="1. ファイルを選択" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				モデルファイルを選択
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				上級ユーザーの場合:3D コンテンツ制作ツールの使用に慣れている方は、高度なアップローダーもお試しください。
-			</text>
-			<button label="アドバンスモードに切り替える" name="switch_to_advanced"/>
-			<text name="Cache location">
-				アップロードするモデルファイルを選択
-			</text>
-			<button label="参照..." label_selected="参照..." name="browse"/>
-			<text name="Model types">
-				Second Life は COLLADA (.dae) ファイルをサポートします。
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				警告:
-			</text>
-			<text name="warning_text">
-				このモデルを Second Life サーバーにアップロードするための最終手順を実行できません。[secondlife:///app/floater/learn_more こちらを参照して]、メッシュモデルをアップロードできるようにアカウントを設定してください。
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				モデルを最適化
-			</text>
-		</panel>
-		<text name="optimize_description">
-			モデルはパフォーマンスを重視して最適化されています。必要に応じて調整してください。
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				次の描画詳細度を作成:高
-			</text>
-			<text name="medium_detail_text">
-				次の描画詳細度を作成:中
-			</text>
-			<text name="low_detail_text">
-				次の描画詳細度を作成:低
-			</text>
-			<text name="lowest_detail_text">
-				次の描画詳細度を作成:最低
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="ジオメトリを再計算" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				ジオメトリのプレビュー
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="プレビュー表示の LOD 設定">
-				<combo_item name="high">
-					高い詳細度
-				</combo_item>
-				<combo_item name="medium">
-					中の詳細度
-				</combo_item>
-				<combo_item name="low">
-					低い詳細度
-				</combo_item>
-				<combo_item name="lowest">
-					最低の詳細度
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				物理作用の調整
-			</text>
-		</panel>
-		<text name="physics_description">
-			モデルの外殻構造のシェイプは弊社が作成します。モデルの目的に応じてシェイプの詳細度を調整してください。
-		</text>
-		<panel name="physics_content">
-			<button label="物理作用を再計算" name="recalculate_physics_btn"/>
-			<button label="再計算中..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				物理作用のプレビュー
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="プレビュー表示の LOD 設定">
-				<combo_item name="high">
-					高い詳細度
-				</combo_item>
-				<combo_item name="medium">
-					中の詳細度
-				</combo_item>
-				<combo_item name="low">
-					低い詳細度
-				</combo_item>
-				<combo_item name="lowest">
-					最低の詳細度
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				確認
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				区画/リージョンへの負荷:[EQUIV] プリム換算値
-			</text>
-			<text name="review_fee">
-				L$ [FEE] のアップロード料金があなたのアカウントに請求されます。
-			</text>
-			<text name="review_confirmation">
-				アップロードボタンをクリックすることにより、モデルに含まれるマテリアルの所有権や使用許可の所持を認めたことになります。
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				アップロード完了
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			モデルがアップロードされました。
-		</text>
-		<text name="inventory_text">
-			それはインベントリの「オブジェクト」フォルダにあります。
-		</text>
-		<text name="charged_fee">
-			あなたのアカウントに L$ [FEE] が請求されました。
-		</text>
-	</panel>
-	<button label="&lt;&lt; 戻る" name="back"/>
-	<button label="次へ&gt;&gt;" name="next"/>
-	<button label="ウェイトと料金の計算 &gt;&gt;" name="calculate"/>
-	<button label="計算中..." name="calculating"/>
-	<button label="アップロード" name="upload" tool_tip="シミュレーターにアップロード"/>
-	<button label="取り消し" name="cancel"/>
-	<button label="閉じる" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		待機状態
-	</string>
-	<string name="status_parse_error">
-		Dae に問題が見つかりました - 詳細についてはログをご参照ください。
-	</string>
-	<string name="status_reading_file">
-		ローディング...
-	</string>
-	<string name="status_generating_meshes">
-		メッシュを作成中
-	</string>
-	<string name="status_vertex_number_overflow">
-		エラー:頂点の数が65534を超過したので中止されました。
-	</string>
-	<string name="bad_element">
-		エラー:要素が無効です
-	</string>
-	<string name="high">
-		高
-	</string>
-	<string name="medium">
-		中
-	</string>
-	<string name="low">
-		低
-	</string>
-	<string name="lowest">
-		最低
-	</string>
-	<string name="mesh_status_good">
-		発送
-	</string>
-	<string name="mesh_status_na">
-		該当なし
-	</string>
-	<string name="mesh_status_none">
-		なし
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		テクスチャ編集可能な面の数は描画詳細度に応じて異なります。
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		メッシュインスタンスの数は描画詳細度に応じて異なります。
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		描画詳細度に対して頂点の数が多すぎます。
-	</string>
-	<string name="mesh_status_missing_lod">
-		必要な描画詳細度が見つかりません。
-	</string>
-	<string name="layer_all">
-		全て
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml b/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
deleted file mode 100644
index 0d07303c910fdd7e9b7ccb989be610ba85fda348..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="CARREGAR ASSISTENTE DE MODELAGEM">
-	<button label="5. Carregar" name="upload_btn"/>
-	<button label="4. Revisar" name="review_btn"/>
-	<button label="3. Física" name="physics_btn"/>
-	<button label="2. Otimizar" name="optimize_btn"/>
-	<button label="1. Selecionra arquivo" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Escolher arquivo de modelo
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Usuários avançados: se você estiver familiarizado com ferramentas de criação de conteúdo 3D, use o Advanced Uploader.
-			</text>
-			<button label="Trocar para avançado" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Escolha o arquivo de modelo para upload
-			</text>
-			<button label="Procurar..." label_selected="Procurar..." name="browse"/>
-			<text name="Model types">
-				O Second Life oferece suporte a arquivos COLLADA (.dae)
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				AVISO:
-			</text>
-			<text name="warning_text">
-				Não será possível concluir a etapa final do upload desse modelo para os servidores do Second Life. [secondlife:///app/floater/learn_more Saiba como] configurar sua conta para uploads de modelos mesh.
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Otimizar modelo
-			</text>
-		</panel>
-		<text name="optimize_description">
-			O modelo foi ajustado para desempenho. Faça novos ajustes, se desejar.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Gerar nível de detalhes: Alto
-			</text>
-			<text name="medium_detail_text">
-				Gerar nível de detalhes: Médio
-			</text>
-			<text name="low_detail_text">
-				Gerar nível de detalhes: Baixo
-			</text>
-			<text name="lowest_detail_text">
-				Gerar nível de detalhes: Mais baixo
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Recalcular geometria" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Visualização da geometria
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="LOD para exibir na renderização de visualização">
-				<combo_item name="high">
-					Máximo de detalhes
-				</combo_item>
-				<combo_item name="medium">
-					Detalhes médios
-				</combo_item>
-				<combo_item name="low">
-					Poucos detalhes
-				</combo_item>
-				<combo_item name="lowest">
-					Mínimo de detalhes
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Ajustar físico
-			</text>
-		</panel>
-		<text name="physics_description">
-			Criaremos uma forma para o corpo externo do modelo. Ajuste o nível de detalhes como necessário para a finalidade desejada de seu modelo.
-		</text>
-		<panel name="physics_content">
-			<button label="Recalcular físico" name="recalculate_physics_btn"/>
-			<button label="Recalculando..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Visualização do físico
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="LOD para exibir na renderização de visualização">
-				<combo_item name="high">
-					Máximo de detalhes
-				</combo_item>
-				<combo_item name="medium">
-					Detalhes médios
-				</combo_item>
-				<combo_item name="low">
-					Poucos detalhes
-				</combo_item>
-				<combo_item name="lowest">
-					Mínimo de detalhes
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Revisar
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Impacto no lote/região: [EQUIV] equivalentes de prim
-			</text>
-			<text name="review_fee">
-				Uma tarifa de upload de L$ [FEE] será debitada da sua conta.
-			</text>
-			<text name="review_confirmation">
-				Ao clicar no botão de upload, você confirma que detém os direitos apropriados sobre o material contido no modelo.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Upload concluído
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Seu modelo foi carregado.
-		</text>
-		<text name="inventory_text">
-			Disponível na pasta Objetos do seu inventário.
-		</text>
-		<text name="charged_fee">
-			L$ [FEE] foram debitados da sua conta.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Voltar" name="back"/>
-	<button label="Próximo &gt;&gt;" name="next"/>
-	<button label="Calcular pesos e tarifa &gt;&gt;" name="calculate"/>
-	<button label="Calculando..." name="calculating"/>
-	<button label="Carregar" name="upload" tool_tip="Carregar no simulador"/>
-	<button label="Cancelar" name="cancel"/>
-	<button label="Fechar" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		Inativo
-	</string>
-	<string name="status_parse_error">
-		Dae parsing - erro, detalhes no log.
-	</string>
-	<string name="status_reading_file">
-		Carregando...
-	</string>
-	<string name="status_generating_meshes">
-		Gerando meshes...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Erro: Número de Vertex acima de 65534. Abortado.
-	</string>
-	<string name="bad_element">
-		Erro: elemento inválido
-	</string>
-	<string name="high">
-		Alto
-	</string>
-	<string name="medium">
-		Médio
-	</string>
-	<string name="low">
-		Baixo
-	</string>
-	<string name="lowest">
-		Mais baixo
-	</string>
-	<string name="mesh_status_good">
-		Entregar!
-	</string>
-	<string name="mesh_status_na">
-		N/D
-	</string>
-	<string name="mesh_status_none">
-		Nenhum
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Cada nível de detalhamento têm um número de faces para textura.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Cada nível de detalhamento têm um número de faces para textura.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		O nível de detalhamento possui vértices demais.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Falta o nível de detalhamento necessário.
-	</string>
-	<string name="layer_all">
-		Tudo
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml b/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
deleted file mode 100644
index c1a63bf7da652d1199fa0a16a0c2a607cd93a1a9..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="ПЕРЕДАТЬ МАСТЕР МОДЕЛИРОВАНИЯ">
-	<button label="5. Передать" name="upload_btn"/>
-	<button label="4. Просмотр" name="review_btn"/>
-	<button label="3. Физика" name="physics_btn"/>
-	<button label="2. Оптимизировать" name="optimize_btn"/>
-	<button label="1. Выбрать файл" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Выберите файл модели
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Пользователям, работающим в расширенном режиме: если вы умеете создавать трехмерные графические объекты, то, возможно, захотите воспользоваться средством Advanced Uploader, которое предоставляет расширенные возможности передачи объектов.
-			</text>
-			<button label="Перейти в расширенный режим" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Выберите файл модели для передачи
-			</text>
-			<button label="Обзор..." label_selected="Обзор..." name="browse"/>
-			<text name="Model types">
-				В Second Life поддерживаются файлы COLLADA (.dae)
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				ВНИМАНИЕ!
-			</text>
-			<text name="warning_text">
-				Вы не сможете завершить передачу этой модели на серверы Second Life. [secondlife:///app/floater/learn_more Узнайте, как] настроить в вашем аккаунте передачу сеточных моделей.
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Оптимизировать модель
-			</text>
-		</panel>
-		<text name="optimize_description">
-			Мы оптимизировали модель для повышения быстродействия. По желанию можно выполнить дополнительную настройку.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Создать уровень детализации: Высокий
-			</text>
-			<text name="medium_detail_text">
-				Создать уровень детализации: Средний
-			</text>
-			<text name="low_detail_text">
-				Создать уровень детализации: Низкий
-			</text>
-			<text name="lowest_detail_text">
-				Создать уровень детализации: Самый низкий
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Пересчитать геометрию" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Просмотр геометрии
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="Детализация при предварительном просмотре">
-				<combo_item name="high">
-					Детально
-				</combo_item>
-				<combo_item name="medium">
-					Средняя детализация
-				</combo_item>
-				<combo_item name="low">
-					Мало деталей
-				</combo_item>
-				<combo_item name="lowest">
-					Минимум деталей
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Настроить физические параметры
-			</text>
-		</panel>
-		<text name="physics_description">
-			Мы создадим форму для внешнего каркаса модели. Настройте уровень детализации формы в соответствии с целями, для которых предназначена модель.
-		</text>
-		<panel name="physics_content">
-			<button label="Пересчитать физические данные" name="recalculate_physics_btn"/>
-			<button label="Пересчет..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Просмотр физических данных
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="Уровень детализации при предварительном просмотре">
-				<combo_item name="high">
-					Детально
-				</combo_item>
-				<combo_item name="medium">
-					Средняя детализация
-				</combo_item>
-				<combo_item name="low">
-					Мало деталей
-				</combo_item>
-				<combo_item name="lowest">
-					Минимум деталей
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Просмотр
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Воздействие на участок/регион: эквивалент в примитивах: [EQUIV]
-			</text>
-			<text name="review_fee">
-				За передачу с вашего счета будет снята плата в размере L$[FEE].
-			</text>
-			<text name="review_confirmation">
-				Нажав кнопку «Передать», вы подтверждаете, что у вас есть надлежащие права на все составляющие модели.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Передача завершена
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Ваша модель передана.
-		</text>
-		<text name="inventory_text">
-			Находится в папке «Объекты» вашего инвентаря.
-		</text>
-		<text name="charged_fee">
-			С вашего счета снято: L$[FEE].
-		</text>
-	</panel>
-	<button label="&lt;&lt; Назад" name="back"/>
-	<button label="Далее &gt;&gt;" name="next"/>
-	<button label="Рассчитать вес и плату &gt;&gt;" name="calculate"/>
-	<button label="Расчет..." name="calculating"/>
-	<button label="Передать" name="upload" tool_tip="Передать в симулятор"/>
-	<button label="Отмена" name="cancel"/>
-	<button label="Закрыть" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		Неактивно
-	</string>
-	<string name="status_parse_error">
-		Проблема при анализе файла DAE – см. подробности в журнале.
-	</string>
-	<string name="status_reading_file">
-		Загрузка...
-	</string>
-	<string name="status_generating_meshes">
-		Создаются меши...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Ошибка. Число вершин превышает 65534. Прервано.
-	</string>
-	<string name="bad_element">
-		Ошибка: недопустимый элемент
-	</string>
-	<string name="high">
-		высокий
-	</string>
-	<string name="medium">
-		средний
-	</string>
-	<string name="low">
-		низкий
-	</string>
-	<string name="lowest">
-		самый низкий
-	</string>
-	<string name="mesh_status_good">
-		Доставлено!
-	</string>
-	<string name="mesh_status_na">
-		Н/Д
-	</string>
-	<string name="mesh_status_none">
-		Нет
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Отличается число текстурируемых граней на уровнях детализации.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Отличается число экземпляров меша на уровнях детализации.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		Слишком много вершин на уровне детализации.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Отсутствует необходимый уровень детализации.
-	</string>
-	<string name="layer_all">
-		Все
-	</string>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml b/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
deleted file mode 100644
index 9d8b982c249d768a4a212e7fff5e79816229b4fd..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="KARÅžIYA MODEL YÃœKLEME SÄ°HÄ°RBAZI">
-	<button label="5. Karşıya Yükle" name="upload_btn"/>
-	<button label="4. Ä°ncele" name="review_btn"/>
-	<button label="3. Fizik" name="physics_btn"/>
-	<button label="2. Optimize et" name="optimize_btn"/>
-	<button label="1. Dosya Seç" name="choose_file_btn"/>
-	<panel name="choose_file_panel">
-		<panel name="choose_file_header_panel">
-			<text name="choose_file_header_text">
-				Model dosyasını seçin
-			</text>
-		</panel>
-		<panel name="choose_file_content">
-			<text name="advanced_users_text">
-				Gelişmiş kullanıcılar: Eğer 3B içerik oluşturma araçlarını kullanmayı biliyorsanız, Gelişmiş Karşıya Yükleyiciyi kullanmak isteyebilirsiniz.
-			</text>
-			<button label="Gelişmişe geç" name="switch_to_advanced"/>
-			<text name="Cache location">
-				Karşıya yüklenecek model dosyasını seçin
-			</text>
-			<button label="Gözat..." label_selected="Gözat..." name="browse"/>
-			<text name="Model types">
-				Second Life, COLLADA (.dae) dosyalarını destekler
-			</text>
-			<text name="dimensions">
-				X         Y         Z
-			</text>
-			<text name="warning_label">
-				UYARI:
-			</text>
-			<text name="warning_text">
-				Bu modelin Second Life sunucularına nihai karşıya yükleme adımını tamamlayamayacaksınız. Hesabınızı örgü modellerinin karşıya yüklenmesi için ayarlamanın [secondlife:///app/floater/learn_more nasıl yapılacağını öğrenin].
-			</text>
-		</panel>
-	</panel>
-	<panel name="optimize_panel">
-		<panel name="optimize_header_panel">
-			<text name="optimize_header_text">
-				Modeli optimize et
-			</text>
-		</panel>
-		<text name="optimize_description">
-			Modeli performans için optimize ettik. İstiyorsanız daha da ayarlayabilirsiniz.
-		</text>
-		<panel name="optimize_content">
-			<text name="high_detail_text">
-				Ayrıntı Seviyesi Oluştur: Yüksek
-			</text>
-			<text name="medium_detail_text">
-				Ayrıntı Seviyesi Oluştur: Orta
-			</text>
-			<text name="low_detail_text">
-				Ayrıntı Seviyesi Oluştur: Düşük
-			</text>
-			<text name="lowest_detail_text">
-				Ayrıntı Seviyesi Oluştur: En Düşük
-			</text>
-		</panel>
-		<panel name="content2">
-			<button label="Geometri hesaplarını tekrar yap" name="recalculate_geometry_btn"/>
-			<text name="lod_label">
-				Geometri önizleme
-			</text>
-			<combo_box name="preview_lod_combo" tool_tip="Önizleme işlemesinde görülecek ayrıntı seviyesi">
-				<combo_item name="high">
-					Çok ayrıntı
-				</combo_item>
-				<combo_item name="medium">
-					Orta düzey ayrıntı
-				</combo_item>
-				<combo_item name="low">
-					Az ayrıntı
-				</combo_item>
-				<combo_item name="lowest">
-					En az ayrıntı
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="physics_panel">
-		<panel name="physics_header_panel">
-			<text name="physics_header_text">
-				Fizik ayarlarını yap
-			</text>
-		</panel>
-		<text name="physics_description">
-			Modelin dış gövdesi için bir şekil oluşturacağız. Modelinizin amacına uygun olarak şeklin ayrıntı seviyesini belirleyin.
-		</text>
-		<panel name="physics_content">
-			<button label="Fizik hesaplarını tekrar yap" name="recalculate_physics_btn"/>
-			<button label="Tekrar hesaplanıyor..." name="recalculating_physics_btn"/>
-			<text name="lod_label">
-				Fizik önizleme
-			</text>
-			<combo_box name="preview_lod_combo2" tool_tip="Önizleme işlemesinde görülecek ayrıntı seviyesi">
-				<combo_item name="high">
-					Çok ayrıntı
-				</combo_item>
-				<combo_item name="medium">
-					Orta düzey ayrıntı
-				</combo_item>
-				<combo_item name="low">
-					Az ayrıntı
-				</combo_item>
-				<combo_item name="lowest">
-					En az ayrıntı
-				</combo_item>
-			</combo_box>
-		</panel>
-	</panel>
-	<panel name="review_panel">
-		<panel name="review_header_panel">
-			<text name="review_header_text">
-				Ä°ncele
-			</text>
-		</panel>
-		<panel name="review_content">
-			<text name="review_prim_equiv">
-				Parsele/bölgeye etkisi: [EQUIV] prim eşdeğerleri
-			</text>
-			<text name="review_fee">
-				Hesabınızdan L$ [FEE] karşıya yükleme ücreti düşülecektir.
-			</text>
-			<text name="review_confirmation">
-				Karşıya yükleme düğmesine tıkladığınızda, modelde yer alan malzeme için ilgili haklara sahip olduğunuzu teyid edersiniz.
-			</text>
-		</panel>
-	</panel>
-	<panel name="upload_panel">
-		<panel name="upload_header_panel">
-			<text name="upload_header_text">
-				Karşıya yükleme bitti
-			</text>
-		</panel>
-		<text name="model_uploaded_text">
-			Modeliniz karşıya yüklendi.
-		</text>
-		<text name="inventory_text">
-			Bunu, envanterinizdeki Nesneler klasöründe bulacaksınız.
-		</text>
-		<text name="charged_fee">
-			Hesabınızdan L$ [FEE] düşüldü.
-		</text>
-	</panel>
-	<button label="&lt;&lt; Geri" name="back"/>
-	<button label="Sonraki &gt;&gt;" name="next"/>
-	<button label="Ağırlıkları ve ücreti hesapla &gt;&gt;" name="calculate"/>
-	<button label="Hesaplanıyor..." name="calculating"/>
-	<button label="Karşıya Yükle" name="upload" tool_tip="Simülatöre karşıya yükle"/>
-	<button label="Ä°ptal" name="cancel"/>
-	<button label="Kapat" name="close"/>
-	<spinner name="import_scale" value="1.0"/>
-	<string name="status_idle">
-		BoÅŸta
-	</string>
-	<string name="status_parse_error">
-		Dae ayrıştırma sorunu - ayrıntılar için günlüğe bakın.
-	</string>
-	<string name="status_reading_file">
-		Yükleniyor...
-	</string>
-	<string name="status_generating_meshes">
-		Örgüler Oluşturuluyor...
-	</string>
-	<string name="status_vertex_number_overflow">
-		Hata: Köşe numarası 65534&apos;ten fazla, işlem durduruldu!
-	</string>
-	<string name="bad_element">
-		Hata: Öğe geçersiz
-	</string>
-	<string name="high">
-		Yüksek
-	</string>
-	<string name="medium">
-		Orta
-	</string>
-	<string name="low">
-		Düşük
-	</string>
-	<string name="lowest">
-		En Düşük
-	</string>
-	<string name="mesh_status_good">
-		Uygula!
-	</string>
-	<string name="mesh_status_na">
-		G/D
-	</string>
-	<string name="mesh_status_none">
-		Hiçbiri
-	</string>
-	<string name="mesh_status_submesh_mismatch">
-		Ayrıntı seviyelerinde farklı sayıda dokulanabilir yüz var.
-	</string>
-	<string name="mesh_status_mesh_mismatch">
-		Ayrıntı seviyelerinde farklı sayıda örgü örneği var.
-	</string>
-	<string name="mesh_status_too_many_vertices">
-		Ayrıntı seviyesinde fazla sayıda köşe var.
-	</string>
-	<string name="mesh_status_missing_lod">
-		Gereken ayrıntı seviyesi eksik.
-	</string>
-	<string name="layer_all">
-		Tümü
-	</string>
-</floater>
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index c970d7997566dadc78bf2aa1091ea3fbb6ea77de..0141a219c5a8416cf93c1d9c6a70885cfd707923 100644
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -111,18 +111,6 @@ namespace tut
 		ensure("1 isMature",   !aa.isMature());
 		ensure("1 isAdult",    !aa.isAdult());
 		
-		// this is kinda bad -- setting this forces maturity to MATURE but !teen != Mature anymore
-		aa.setTeen(false);
-		ensure("2 isTeen",     !aa.isTeen());
-		ensure("2 isMature",   aa.isMature());
-		ensure("2 isAdult",    !aa.isAdult());
-
-		// have to flip it back and make sure it still works
-		aa.setTeen(true);
-		ensure("3 isTeen",     aa.isTeen());
-		ensure("3 isMature",   !aa.isMature());
-		ensure("3 isAdult",    !aa.isAdult());		
-
 		// check the conversion routine
 		ensure_equals("1 conversion", SIM_ACCESS_PG, aa.convertTextToMaturity('P'));
 		ensure_equals("2 conversion", SIM_ACCESS_MATURE, aa.convertTextToMaturity('M'));
@@ -131,21 +119,21 @@ namespace tut
 		
 		// now try the other method of setting it - PG
 		aa.setMaturity('P');
-		ensure("4 isTeen",     aa.isTeen());
-		ensure("4 isMature",   !aa.isMature());
-		ensure("4 isAdult",    !aa.isAdult());
+		ensure("2 isTeen",     aa.isTeen());
+		ensure("2 isMature",   !aa.isMature());
+		ensure("2 isAdult",    !aa.isAdult());
 		
 		// Mature
 		aa.setMaturity('M');
-		ensure("5 isTeen",     !aa.isTeen());
-		ensure("5 isMature",   aa.isMature());
-		ensure("5 isAdult",    !aa.isAdult());
+		ensure("3 isTeen",     !aa.isTeen());
+		ensure("3 isMature",   aa.isMature());
+		ensure("3 isAdult",    !aa.isAdult());
 		
 		// Adult
 		aa.setMaturity('A');
-		ensure("6 isTeen",     !aa.isTeen());
-		ensure("6 isMature",   aa.isMature());
-		ensure("6 isAdult",    aa.isAdult());
+		ensure("4 isTeen",     !aa.isTeen());
+		ensure("4 isMature",   aa.isMature());
+		ensure("4 isAdult",    aa.isAdult());
 		
 	}
 
@@ -239,18 +227,6 @@ namespace tut
 		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
 		LLAgentAccess aa(cgr);
 		
-		ensure("1 transition starts false", !aa.isInTransition());
-		aa.setTransition();
-		ensure("2 transition now true", aa.isInTransition());
-	}
-
-	template<> template<>
-	void agentaccess_object_t::test<6>()
-	{
-		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
-		LLAgentAccess aa(cgr);
-		
 		cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
 		aa.setMaturity('M');
 		ensure("1 preferred maturity pegged to M when maturity is M", cgr.getU32("PreferredMaturity") == SIM_ACCESS_MATURE);
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 36267803e3e99360e8222e8a2187927018a44441..7c6b5403e1df44391369b6ebd40a95e2c477abc7 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -91,6 +91,13 @@ def construct(self):
 
                 # ... and the entire windlight directory
                 self.path("windlight")
+
+                # ... and the included spell checking dictionaries
+                pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+                if self.prefix(src=pkgdir,dst=""):
+                    self.path("dictionaries")
+                    self.end_prefix(pkgdir)
+
                 self.end_prefix("app_settings")
 
             if self.prefix(src="character"):
@@ -393,6 +400,9 @@ def construct(self):
             self.path("ssleay32.dll")
             self.path("libeay32.dll")
 
+            # Hunspell
+            self.path("libhunspell.dll")
+
             # For google-perftools tcmalloc allocator.
             try:
                 if self.args['configuration'].lower() == 'debug':
@@ -659,6 +669,7 @@ def construct(self):
 
             # copy additional libs in <bundle>/Contents/MacOS/
             self.path("../packages/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib")
+            self.path("../packages/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib")
 
             self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install")
 
@@ -1043,7 +1054,11 @@ def construct(self):
             self.path("libopenjpeg.so*")
             self.path("libdirectfb-1.4.so.5")
             self.path("libfusion-1.4.so.5")
+            self.path("libdirect-1.4.so.5.0.4")
             self.path("libdirect-1.4.so.5")
+            self.path("libhunspell-1.3.so")
+            self.path("libhunspell-1.3.so.0")
+            self.path("libhunspell-1.3.so.0.0.0")
             self.path("libalut.so")
             self.path("libopenal.so", "libopenal.so.1")
             self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname