diff --git a/autobuild.xml b/autobuild.xml
index eacf11fb0ff5580339ee776b5381aefb03f29045..a8203bb643cdbd5f5c926dc2dae05a03709f478e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>471b0b350955152fd87518575057dfc4</string>
+              <string>322dd6c45c384d454ae14ef127984a4e</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60326/566593/bugsplat-1.0.7.542667-darwin64-542667.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65457/612879/bugsplat-1.0.7.546418-darwin64-546418.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>70e8bf46145c4cbae6f93e8b70ba5499</string>
+              <string>010a0e73c0fddaa2316411803fad8e69</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60320/566541/bugsplat-3.6.0.4.542667-windows-542667.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65456/612876/bugsplat-3.6.0.8.546418-windows-546418.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a73696e859fad3f19f835740815a2bd3</string>
+              <string>7e8530762e7b50663708a888c23b8780</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60321/566542/bugsplat-3.6.0.4.542667-windows64-542667.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65455/612874/bugsplat-3.6.0.8.546418-windows64-546418.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.7.542667</string>
+        <string>3.6.0.8.546418</string>
       </map>
       <key>colladadom</key>
       <map>
@@ -580,9 +580,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e145f8ea99a21712434e0e868d1885dc</string>
+              <string>cc26af2ebfa241891caca829a6e46b88</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/62333/588183/dullahan-1.7.0.202006240858_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-544091.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65005/607316/dullahan-1.7.0.202008031101_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-546064.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -592,9 +592,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>fdbbbfc377e28cba664f2b1c54ea6086</string>
+              <string>4e5b9e2fe65d94e30a4f3d831c767199</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/62331/588162/dullahan-1.7.0.202006241556_81.3.10_gb223419_chromium-81.0.4044.138-windows-544091.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65004/607304/dullahan-1.7.0.202008031759_81.3.10_gb223419_chromium-81.0.4044.138-windows-546064.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -604,16 +604,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d85a32d905b199534e8feafa34b28e39</string>
+              <string>6f7bf7f915f3d75dbdad08a2d41ca74e</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/62332/588168/dullahan-1.7.0.202006241556_81.3.10_gb223419_chromium-81.0.4044.138-windows64-544091.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65003/607308/dullahan-1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138-windows64-546064.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.7.0.202006240858_81.3.10_gb223419_chromium-81.0.4044.138</string>
+        <string>1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138</string>
       </map>
       <key>elfio</key>
       <map>
@@ -748,9 +748,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dc4c9122de8bf77f34cfc8227d10a272</string>
+              <string>89c37441a806ed80c0102d380eec6fd0</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59038/554626/fmodstudio-2.00.07.541681-darwin64-541681.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65400/612632/fmodstudio-2.00.11.546392-darwin64-546392.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -760,9 +760,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c491bdc1690f3d920c66be509ccc6ef2</string>
+              <string>5283050c22d31877cd9e0afbe6feb9fc</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59039/554632/fmodstudio-2.00.07.541681-linux-541681.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65398/612630/fmodstudio-2.00.11.546392-linux-546392.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -772,9 +772,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ae75cdb1cc9da824c9e270bf97bfdd6c</string>
+              <string>5a3c78f4a77ae6477986e33836725e8b</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/54589/506866/fmodstudio-2.00.07.538806-linux64-538806.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65399/612631/fmodstudio-2.00.11.546392-linux64-546392.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux64</string>
@@ -784,9 +784,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7f0294b038eab2d89ecc73bbf08b6d94</string>
+              <string>0f44323b0d03b7d0d8a17eec83e103ce</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59042/554668/fmodstudio-2.00.07.541681-windows-541681.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65401/612647/fmodstudio-2.00.11.546392-windows-546392.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -796,16 +796,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>da2e8e2b809d8fe635ee437baa2a7386</string>
+              <string>462d28eacf731a5d36ab031e7071c32a</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59041/554656/fmodstudio-2.00.07.541681-windows64-541681.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/65402/612648/fmodstudio-2.00.11.546392-windows64-546392.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>2.00.07.541681</string>
+        <string>2.00.11.546392</string>
       </map>
       <key>fontconfig</key>
       <map>
@@ -2187,16 +2187,18 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b677ee43822212f0a27c838dc8bf3623</string>
+              <string>9f4687d7d328b0c13a9e651e805e880a</string>
+              <key>hash_algorithm</key>
+              <string>md5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/67622/646614/llca-202009010215.548269-common-548269.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/71501/691487/llca-202011010215.551526-common-551526.tar.bz2</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
         <key>version</key>
-        <string>202009010215.548269</string>
+        <string>202011010215.551526</string>
       </map>
       <key>llphysicsextensions_source</key>
       <map>
@@ -3495,7 +3497,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
       <key>canonical_repo</key>
       <string>https://bitbucket.org/lindenlab/viewer</string>
       <key>copyright</key>
-      <string>Copyright (c) 2014, Linden Research, Inc.</string>
+      <string>Copyright (c) 2020, Linden Research, Inc.</string>
       <key>description</key>
       <string>Second Life Viewer</string>
       <key>license</key>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index df51b5b0429ea0590a3607574caf34d5dff98344..5a389e30cd71f7154b3870748bbaab48de120a2d 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -224,6 +224,9 @@ Ansariel Hiller
 	SL-10385
 	SL-10891
 	SL-10675
+	SL-13364
+	SL-13858
+	SL-13697
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
@@ -836,7 +839,9 @@ Khyota Wulluf
 Kimar Coba
 Kithrak Kirkorian
 Kitty Barnett
+	BUG-228664
 	BUG-228665
+	BUG-228719
 	VWR-19699
 	STORM-288
 	STORM-799
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 3dab632aefab6707c64a352cc84fca48679e7420..a90b2945504298cfeee03477d6d31c3183ba1b40 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -180,7 +180,7 @@ LLApp::~LLApp()
 	
 	if(mExceptionHandler != 0) delete mExceptionHandler;
 
-	SUBSYSTEM_CLEANUP(LLCommon);
+	SUBSYSTEM_CLEANUP_DBG(LLCommon);
 }
 
 // static
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 984e90f37627116b3f7eb9f2b7ad132c280d830a..db947658719b2aa453310bbb5700e563ad8621be 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -68,7 +68,7 @@ void ll_cleanup_apr()
 {
 	gAPRInitialized = false;
 
-	LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
+	LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
 
 	LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
 
diff --git a/indra/llcommon/llcleanup.cpp b/indra/llcommon/llcleanup.cpp
index c5283507bfc0d8831aeeae7b6a0cff8e0946c2ec..1f34c2036a3f560febaeb4db17a7d16612b3a1f7 100644
--- a/indra/llcommon/llcleanup.cpp
+++ b/indra/llcommon/llcleanup.cpp
@@ -20,10 +20,13 @@
 #include "llerror.h"
 #include "llerrorcontrol.h"
 
-void log_subsystem_cleanup(const char* file, int line, const char* function,
+void log_subsystem_cleanup(LLError::ELevel level,
+                           const char* file,
+                           int line,
+                           const char* function,
                            const char* classname)
 {
-    LL_INFOS("Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
+    LL_VLOGS(level, "Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
                         << "calling " << classname << "::cleanupClass() in "
                         << function << LL_ENDL;
 }
diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h
index a319171b5f1891d06969585c9f9a75e02ef7149c..0f567ed5f6afcd38e3fb42cc54668cd2556cf3d4 100644
--- a/indra/llcommon/llcleanup.h
+++ b/indra/llcommon/llcleanup.h
@@ -21,13 +21,22 @@
 // shutdown schemes.
 #define SUBSYSTEM_CLEANUP(CLASSNAME)                                    \
     do {                                                                \
-        log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
+        log_subsystem_cleanup(LLError::LEVEL_INFO, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
+        CLASSNAME::cleanupClass();                                      \
+    } while (0)
+
+#define SUBSYSTEM_CLEANUP_DBG(CLASSNAME)                                    \
+    do {                                                                \
+        log_subsystem_cleanup(LLError::LEVEL_DEBUG, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
         CLASSNAME::cleanupClass();                                      \
     } while (0)
 // Use ancient do { ... } while (0) macro trick to permit a block of
 // statements with the same syntax as a single statement.
 
-void log_subsystem_cleanup(const char* file, int line, const char* function,
+void log_subsystem_cleanup(LLError::ELevel level,
+                           const char* file,
+                           int line,
+                           const char* function,
                            const char* classname);
 
 #endif /* ! defined(LL_LLCLEANUP_H) */
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 2d665c611b47418f6594eff3cc5a57e1200ec27b..96be913d17a07cface3713ddf5ae95ecb8557b73 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -63,7 +63,7 @@ void LLCommon::cleanupClass()
 	sMasterThreadRecorder = NULL;
 	LLTrace::set_master_thread_recorder(NULL);
 	LLThreadSafeRefCount::cleanupThreadSafeRefCount();
-	SUBSYSTEM_CLEANUP(LLTimer);
+	SUBSYSTEM_CLEANUP_DBG(LLTimer);
 	if (sAprInitialized)
 	{
 		ll_cleanup_apr();
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 411412c883965fbc86ea4d9b6cf7c70ce7d414e6..f876b8ee4a50676fde4c2fae872585c6f6855d8f 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -332,12 +332,9 @@ namespace LLError
 		}
 		// huh, that's odd, we should see one or the other prefix -- but don't
 		// try to log unless logging is already initialized
-		if (is_available())
-		{
-			// in Python, " or ".join(vector) -- but in C++, a PITB
-			LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
-				<< name << "'" << LL_ENDL;
-		}
+		// in Python, " or ".join(vector) -- but in C++, a PITB
+		LL_DEBUGS() << "Did not see 'class' or 'struct' prefix on '"
+			<< name << "'" << LL_ENDL;
 		return name;
 
 #else  // neither GCC nor Visual Studio
@@ -438,9 +435,12 @@ namespace
 	typedef std::vector<LLError::RecorderPtr> Recorders;
 	typedef std::vector<LLError::CallSite*> CallSiteVector;
 
-	class Globals : public LLSingleton<Globals>
+	class Globals
 	{
-		LLSINGLETON(Globals);
+    public:
+        static Globals* getInstance();
+    protected:
+		Globals();
 	public:
 		std::ostringstream messageStream;
 		bool messageStreamInUse;
@@ -460,6 +460,16 @@ namespace
 	{
 	}
 
+    Globals* Globals::getInstance()
+    {
+        // According to C++11 Function-Local Initialization
+        // of static variables is supposed to be thread safe
+        // without risk of deadlocks.
+        static Globals inst;
+
+        return &inst;
+    }
+
 	void Globals::addCallSite(LLError::CallSite& site)
 	{
 		callSites.push_back(&site);
@@ -512,14 +522,17 @@ namespace LLError
 
 	typedef LLPointer<SettingsConfig> SettingsConfigPtr;
 
-	class Settings : public LLSingleton<Settings>
+	class Settings
 	{
-		LLSINGLETON(Settings);
+    public:
+        static Settings* getInstance();
+    protected:
+		Settings();
 	public:
 		SettingsConfigPtr getSettingsConfig();
 
 		void reset();
-		SettingsStoragePtr saveAndReset();
+		SettingsStoragePtr saveAndReset(); 
 		void restore(SettingsStoragePtr pSettingsStorage);
 		
 	private:
@@ -553,6 +566,16 @@ namespace LLError
 	{
 	}
 
+    Settings* Settings::getInstance()
+    {
+        // According to C++11 Function-Local Initialization
+        // of static variables is supposed to be thread safe
+        // without risk of deadlocks.
+        static Settings inst;
+
+        return &inst;
+    }
+
 	SettingsConfigPtr Settings::getSettingsConfig()
 	{
 		return mSettingsConfig;
@@ -577,11 +600,6 @@ namespace LLError
 		SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get()));
 		mSettingsConfig = newSettingsConfig;
 	}
-
-	bool is_available()
-	{
-		return Settings::instanceExists() && Globals::instanceExists();
-	}
 }
 
 namespace LLError
@@ -1028,7 +1046,7 @@ namespace LLError
     std::pair<boost::shared_ptr<RECORDER>, Recorders::iterator>
     findRecorderPos()
     {
-        SettingsConfigPtr s = Settings::instance().getSettingsConfig();
+        SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
         // Since we promise to return an iterator, use a classic iterator
         // loop.
         auto end{s->mRecorders.end()};
@@ -1071,7 +1089,7 @@ namespace LLError
         auto found = findRecorderPos<RECORDER>();
         if (found.first)
         {
-            SettingsConfigPtr s = Settings::instance().getSettingsConfig();
+            SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
             s->mRecorders.erase(found.second);
         }
         return bool(found.first);
@@ -1307,14 +1325,6 @@ namespace LLError
 			return false;
 		}
 
-		// If we hit a logging request very late during shutdown processing,
-		// when either of the relevant LLSingletons has already been deleted,
-		// DO NOT resurrect them.
-		if (Settings::wasDeleted() || Globals::wasDeleted())
-		{
-			return false;
-		}
-
 		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
 		
 		s->mShouldLogCallCounter++;
@@ -1353,10 +1363,8 @@ namespace LLError
 	std::ostringstream* Log::out()
 	{
 		LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
-		// If we hit a logging request very late during shutdown processing,
-		// when either of the relevant LLSingletons has already been deleted,
-		// DO NOT resurrect them.
-		if (lock.isLocked() && ! (Settings::wasDeleted() || Globals::wasDeleted()))
+
+		if (lock.isLocked())
 		{
 			Globals* g = Globals::getInstance();
 
@@ -1378,14 +1386,6 @@ namespace LLError
 			return;
 		}
 
-		// If we hit a logging request very late during shutdown processing,
-		// when either of the relevant LLSingletons has already been deleted,
-		// DO NOT resurrect them.
-		if (Settings::wasDeleted() || Globals::wasDeleted())
-		{
-			return;
-		}
-
 		if(strlen(out->str().c_str()) < 128)
 		{
 			strcpy(message, out->str().c_str());
@@ -1418,14 +1418,6 @@ namespace LLError
 			return;
 		}
 
-		// If we hit a logging request very late during shutdown processing,
-		// when either of the relevant LLSingletons has already been deleted,
-		// DO NOT resurrect them.
-		if (Settings::wasDeleted() || Globals::wasDeleted())
-		{
-			return;
-		}
-
 		Globals* g = Globals::getInstance();
 		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
 
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index bfa22690252d5716e6470fd4fef301694d10e21d..25786d5457c7e8b309fb0f052c39497ab508942a 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -203,11 +203,6 @@ namespace LLError
 
 	LL_COMMON_API std::string abbreviateFile(const std::string& filePath);
 	LL_COMMON_API int shouldLogCallCount();
-
-	// Check whether Globals exists. This should only be used by LLSingleton
-	// infrastructure to avoid trying to log when our internal LLSingleton is
-	// unavailable -- circularity ensues.
-	LL_COMMON_API bool is_available();
 };
 
 #endif // LL_LLERRORCONTROL_H
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index d3d25201b2a60145db77fdb513a03a19ec517b74..83a4b64e8f8591a7b7d686fb46149e26950b31bf 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -28,7 +28,7 @@
 #include "llsingleton.h"
 
 #include "llerror.h"
-#include "llerrorcontrol.h"         // LLError::is_available()
+#include "llerrorcontrol.h"
 #include "lldependencies.h"
 #include "llexception.h"
 #include "llcoros.h"
@@ -41,8 +41,6 @@
 namespace {
 void log(LLError::ELevel level,
          const char* p1, const char* p2, const char* p3, const char* p4);
-
-bool oktolog();
 } // anonymous namespace
 
 // Our master list of all LLSingletons is itself an LLSingleton. We used to
@@ -279,8 +277,6 @@ void LLSingletonBase::reset_initializing(list_t::size_type size)
 
 void LLSingletonBase::MasterList::LockedInitializing::log(const char* verb, const char* name)
 {
-    if (oktolog())
-    {
         LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';';
         if (mList)
         {
@@ -292,7 +288,6 @@ void LLSingletonBase::MasterList::LockedInitializing::log(const char* verb, cons
             }
         }
         LL_ENDL;
-    }
 }
 
 void LLSingletonBase::capture_dependency()
@@ -455,33 +450,11 @@ void LLSingletonBase::deleteAll()
 
 /*---------------------------- Logging helpers -----------------------------*/
 namespace {
-bool oktolog()
-{
-    // See comments in log() below.
-    return LLError::is_available();
-}
 
 void log(LLError::ELevel level,
          const char* p1, const char* p2, const char* p3, const char* p4)
 {
-    // The is_available() test below ensures that we'll stop logging once
-    // LLError has been cleaned up. If we had a similar portable test for
-    // std::cerr, this would be a good place to use it.
-
-    // Check LLError::is_available() because some of LLError's infrastructure
-    // is itself an LLSingleton. If that LLSingleton has not yet been
-    // initialized, trying to log will engage LLSingleton machinery... and
-    // around and around we go.
-    if (LLError::is_available())
-    {
-        LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
-    }
-    else
-    {
-        // Caller may be a test program, or something else whose stderr is
-        // visible to the user.
-        std::cerr << p1 << p2 << p3 << p4 << std::endl;
-    }
+    LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
 }
 
 } // anonymous namespace        
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 408adbde2b61babdcf524fe1b73e3abf475da5de..7bea8e9f9c353e78666f73f03b686c530c0d1e43 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -1017,8 +1017,8 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd
         }
         else
         {
-            // disable any default verification for server certs
-            // Ex: setting urls (assume non-SL) for parcel media in LLFloaterURLEntry
+            // disable any default verification for server certs
+            // Ex: setting urls (assume non-SL) for parcel media in LLFloaterURLEntry
             SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
         }
 		// set the verification callback.
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 11647c5518587d0fd841c0e32bc3284a7bc5bb39..18bc1b5a9102a715c06e913d588abac42ba4f83c 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -41,7 +41,7 @@
 /// Exported functions
 ///----------------------------------------------------------------------------
 static const std::string INV_ITEM_ID_LABEL("item_id");
-static const std::string INV_FOLDER_ID_LABEL("folder_id");
+static const std::string INV_FOLDER_ID_LABEL("cat_id");
 static const std::string INV_PARENT_ID_LABEL("parent_id");
 static const std::string INV_ASSET_TYPE_LABEL("type");
 static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
@@ -228,22 +228,6 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)
 	return TRUE;
 }
 
-// exportFile should be replaced with exportLegacyStream
-// not sure whether exportLegacyStream(llofstream(fp)) would work, fp may need to get icramented...
-BOOL LLInventoryObject::exportFile(LLFILE* fp, BOOL) const
-{
-	std::string uuid_str;
-	fprintf(fp, "\tinv_object\t0\n\t{\n");
-	mUUID.toString(uuid_str);
-	fprintf(fp, "\t\tobj_id\t%s\n", uuid_str.c_str());
-	mParentUUID.toString(uuid_str);
-	fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
-	fprintf(fp,"\t}\n");
-	return TRUE;
-}
-
 BOOL LLInventoryObject::exportLegacyStream(std::ostream& output_stream, BOOL) const
 {
 	std::string uuid_str;
@@ -603,215 +587,6 @@ BOOL LLInventoryItem::unpackMessage(LLMessageSystem* msg, const char* block, S32
 #endif
 }
 
-// virtual
-BOOL LLInventoryItem::importFile(LLFILE* fp)
-{
-	// *NOTE: Changing the buffer size will require changing the scanf
-	// calls below.
-	char buffer[MAX_STRING];	/* Flawfinder: ignore */
-	char keyword[MAX_STRING];	/* Flawfinder: ignore */	
-	char valuestr[MAX_STRING];	/* Flawfinder: ignore */
-	char junk[MAX_STRING];	/* Flawfinder: ignore */
-	BOOL success = TRUE;
-
-	keyword[0] = '\0';
-	valuestr[0] = '\0';
-
-	mInventoryType = LLInventoryType::IT_NONE;
-	mAssetUUID.setNull();
-	while(success && (!feof(fp)))
-	{
-		if (fgets(buffer, MAX_STRING, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-		
-		sscanf(buffer, " %254s %254s", keyword, valuestr);	/* Flawfinder: ignore */
-		if(0 == strcmp("{",keyword))
-		{
-			continue;
-		}
-		if(0 == strcmp("}", keyword))
-		{
-			break;
-		}
-		else if(0 == strcmp("item_id", keyword))
-		{
-			mUUID.set(valuestr);
-		}
-		else if(0 == strcmp("parent_id", keyword))
-		{
-			mParentUUID.set(valuestr);
-		}
-		else if(0 == strcmp("permissions", keyword))
-		{
-			success = mPermissions.importFile(fp);
-		}
-		else if(0 == strcmp("sale_info", keyword))
-		{
-			// Sale info used to contain next owner perm. It is now in
-			// the permissions. Thus, we read that out, and fix legacy
-			// objects. It's possible this op would fail, but it
-			// should pick up the vast majority of the tasks.
-			BOOL has_perm_mask = FALSE;
-			U32 perm_mask = 0;
-			success = mSaleInfo.importFile(fp, has_perm_mask, perm_mask);
-			if(has_perm_mask)
-			{
-				if(perm_mask == PERM_NONE)
-				{
-					perm_mask = mPermissions.getMaskOwner();
-				}
-				// fair use fix.
-				if(!(perm_mask & PERM_COPY))
-				{
-					perm_mask |= PERM_TRANSFER;
-				}
-				mPermissions.setMaskNext(perm_mask);
-			}
-		}
-		else if(0 == strcmp("shadow_id", keyword))
-		{
-			mAssetUUID.set(valuestr);
-			LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
-			cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
-		}
-		else if(0 == strcmp("asset_id", keyword))
-		{
-			mAssetUUID.set(valuestr);
-		}
-		else if(0 == strcmp("type", keyword))
-		{
-			mType = LLAssetType::lookup(valuestr);
-		}
-		else if(0 == strcmp("inv_type", keyword))
-		{
-			mInventoryType = LLInventoryType::lookup(std::string(valuestr));
-		}
-		else if(0 == strcmp("flags", keyword))
-		{
-			sscanf(valuestr, "%x", &mFlags);
-		}
-		else if(0 == strcmp("name", keyword))
-		{
-			//strcpy(valuestr, buffer + strlen(keyword) + 3);
-			// *NOTE: Not ANSI C, but widely supported.
-			sscanf(	/* Flawfinder: ignore */
-				buffer,
-				" %254s%254[\t]%254[^|]",
-				keyword, junk, valuestr);
-
-			// IW: sscanf chokes and puts | in valuestr if there's no name
-			if (valuestr[0] == '|')
-			{
-				valuestr[0] = '\000';
-			}
-
-			mName.assign(valuestr);
-			LLStringUtil::replaceNonstandardASCII(mName, ' ');
-			LLStringUtil::replaceChar(mName, '|', ' ');
-		}
-		else if(0 == strcmp("desc", keyword))
-		{
-			//strcpy(valuestr, buffer + strlen(keyword) + 3);
-			// *NOTE: Not ANSI C, but widely supported.
-			sscanf(	/* Flawfinder: ignore */
-				buffer,
-				" %254s%254[\t]%254[^|]",
-				keyword, junk, valuestr);
-
-			if (valuestr[0] == '|')
-			{
-				valuestr[0] = '\000';
-			}
-
-			disclaimMem(mDescription);
-			mDescription.assign(valuestr);
-			claimMem(mDescription);
-			LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
-			/* TODO -- ask Ian about this code
-			const char *donkey = mDescription.c_str();
-			if (donkey[0] == '|')
-			{
-				LL_ERRS() << "Donkey" << LL_ENDL;
-			}
-			*/
-		}
-		else if(0 == strcmp("creation_date", keyword))
-		{
-			S32 date;
-			sscanf(valuestr, "%d", &date);
-			mCreationDate = date;
-		}
-		else
-		{
-			LL_WARNS() << "unknown keyword '" << keyword
-					<< "' in inventory import of item " << mUUID << LL_ENDL;
-		}
-	}
-
-	// Need to convert 1.0 simstate files to a useful inventory type
-	// and potentially deal with bad inventory tyes eg, a landmark
-	// marked as a texture.
-	if((LLInventoryType::IT_NONE == mInventoryType)
-	   || !inventory_and_asset_types_match(mInventoryType, mType))
-	{
-		LL_DEBUGS() << "Resetting inventory type for " << mUUID << LL_ENDL;
-		mInventoryType = LLInventoryType::defaultForAssetType(mType);
-	}
-
-	mPermissions.initMasks(mInventoryType);
-
-	return success;
-}
-
-BOOL LLInventoryItem::exportFile(LLFILE* fp, BOOL include_asset_key) const
-{
-	std::string uuid_str;
-	fprintf(fp, "\tinv_item\t0\n\t{\n");
-	mUUID.toString(uuid_str);
-	fprintf(fp, "\t\titem_id\t%s\n", uuid_str.c_str());
-	mParentUUID.toString(uuid_str);
-	fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
-	mPermissions.exportFile(fp);
-
-	// Check for permissions to see the asset id, and if so write it
-	// out as an asset id. Otherwise, apply our cheesy encryption.
-	if(include_asset_key)
-	{
-		U32 mask = mPermissions.getMaskBase();
-		if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
-		   || (mAssetUUID.isNull()))
-		{
-			mAssetUUID.toString(uuid_str);
-			fprintf(fp, "\t\tasset_id\t%s\n", uuid_str.c_str());
-		}
-		else
-		{
-			LLUUID shadow_id(mAssetUUID);
-			LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
-			cipher.encrypt(shadow_id.mData, UUID_BYTES);
-			shadow_id.toString(uuid_str);
-			fprintf(fp, "\t\tshadow_id\t%s\n", uuid_str.c_str());
-		}
-	}
-	else
-	{
-		LLUUID::null.toString(uuid_str);
-		fprintf(fp, "\t\tasset_id\t%s\n", uuid_str.c_str());
-	}
-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
-	if(!inv_type_str.empty()) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str.c_str());
-	fprintf(fp, "\t\tflags\t%08x\n", mFlags);
-	mSaleInfo.exportFile(fp);
-	fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
-	fprintf(fp, "\t\tdesc\t%s|\n", mDescription.c_str());
-	fprintf(fp, "\t\tcreation_date\t%d\n", (S32) mCreationDate);
-	fprintf(fp,"\t}\n");
-	return TRUE;
-}
-
 // virtual
 BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
 {
@@ -1463,90 +1238,7 @@ void LLInventoryCategory::unpackMessage(LLMessageSystem* msg,
 	msg->getStringFast(block, _PREHASH_Name, mName, block_num);
 	LLStringUtil::replaceNonstandardASCII(mName, ' ');
 }
-	
-// virtual
-BOOL LLInventoryCategory::importFile(LLFILE* fp)
-{
-	// *NOTE: Changing the buffer size will require changing the scanf
-	// calls below.
-	char buffer[MAX_STRING];	/* Flawfinder: ignore */
-	char keyword[MAX_STRING];	/* Flawfinder: ignore */
-	char valuestr[MAX_STRING];	/* Flawfinder: ignore */
 
-	keyword[0] = '\0';
-	valuestr[0] = '\0';
-	while(!feof(fp))
-	{
-		if (fgets(buffer, MAX_STRING, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-		
-		sscanf(	/* Flawfinder: ignore */
-			buffer,
-			" %254s %254s",
-			keyword, valuestr);
-		if(0 == strcmp("{",keyword))
-		{
-			continue;
-		}
-		if(0 == strcmp("}", keyword))
-		{
-			break;
-		}
-		else if(0 == strcmp("cat_id", keyword))
-		{
-			mUUID.set(valuestr);
-		}
-		else if(0 == strcmp("parent_id", keyword))
-		{
-			mParentUUID.set(valuestr);
-		}
-		else if(0 == strcmp("type", keyword))
-		{
-			mType = LLAssetType::lookup(valuestr);
-		}
-		else if(0 == strcmp("pref_type", keyword))
-		{
-			mPreferredType = LLFolderType::lookup(valuestr);
-		}
-		else if(0 == strcmp("name", keyword))
-		{
-			//strcpy(valuestr, buffer + strlen(keyword) + 3);
-			// *NOTE: Not ANSI C, but widely supported.
-			sscanf(	/* Flawfinder: ignore */
-				buffer,
-				" %254s %254[^|]",
-				keyword, valuestr);
-			mName.assign(valuestr);
-			LLStringUtil::replaceNonstandardASCII(mName, ' ');
-			LLStringUtil::replaceChar(mName, '|', ' ');
-		}
-		else
-		{
-			LL_WARNS() << "unknown keyword '" << keyword
-					<< "' in inventory import category "  << mUUID << LL_ENDL;
-		}
-	}
-	return TRUE;
-}
-
-BOOL LLInventoryCategory::exportFile(LLFILE* fp, BOOL) const
-{
-	std::string uuid_str;
-	fprintf(fp, "\tinv_category\t0\n\t{\n");
-	mUUID.toString(uuid_str);
-	fprintf(fp, "\t\tcat_id\t%s\n", uuid_str.c_str());
-	mParentUUID.toString(uuid_str);
-	fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	fprintf(fp, "\t\tpref_type\t%s\n", LLFolderType::lookup(mPreferredType).c_str());
-	fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
-	fprintf(fp,"\t}\n");
-	return TRUE;
-}
-
-	
 // virtual
 BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream)
 {
@@ -1625,6 +1317,45 @@ BOOL LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, BOOL)
 	return TRUE;
 }
 
+LLSD LLInventoryCategory::exportLLSD() const
+{
+	LLSD cat_data;
+	cat_data[INV_FOLDER_ID_LABEL] = mUUID;
+	cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
+	cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
+	cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
+	cat_data[INV_NAME_LABEL] = mName;
+
+	return cat_data;
+}
+
+bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
+{
+	if (cat_data.has(INV_FOLDER_ID_LABEL))
+	{
+		setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
+	}
+	if (cat_data.has(INV_PARENT_ID_LABEL))
+	{
+		setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
+	}
+	if (cat_data.has(INV_ASSET_TYPE_LABEL))
+	{
+		setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
+	}
+	if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
+	{
+		setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
+	}
+	if (cat_data.has(INV_NAME_LABEL))
+	{
+		mName = cat_data[INV_NAME_LABEL].asString();
+		LLStringUtil::replaceNonstandardASCII(mName, ' ');
+		LLStringUtil::replaceChar(mName, '|', ' ');
+	}
+
+	return true;
+}
 ///----------------------------------------------------------------------------
 /// Local function definitions
 ///----------------------------------------------------------------------------
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 70b200e139401504ad00f0539bd89cf23c5c9146..024afc109cdda02110a9b00add7cc9b0f153e1c6 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -95,8 +95,7 @@ class LLInventoryObject : public LLRefCount, public LLTrace::MemTrackable<LLInve
 	//   Implemented here so that a minimal information set can be transmitted
 	//   between simulator and viewer.
 	//--------------------------------------------------------------------
-	// virtual BOOL importFile(LLFILE* fp);
-	virtual BOOL exportFile(LLFILE* fp, BOOL include_asset_key = TRUE) const;
+
 	virtual BOOL importLegacyStream(std::istream& input_stream);
 	virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
 
@@ -197,8 +196,6 @@ class LLInventoryItem : public LLInventoryObject
 	// File Support
 	//--------------------------------------------------------------------
 public:
-	virtual BOOL importFile(LLFILE* fp);
-	virtual BOOL exportFile(LLFILE* fp, BOOL include_asset_key = TRUE) const;
 	virtual BOOL importLegacyStream(std::istream& input_stream);
 	virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
 
@@ -269,11 +266,11 @@ class LLInventoryCategory : public LLInventoryObject
 	// File Support
 	//--------------------------------------------------------------------
 public:
-	virtual BOOL importFile(LLFILE* fp);
-	virtual BOOL exportFile(LLFILE* fp, BOOL include_asset_key = TRUE) const;
 	virtual BOOL importLegacyStream(std::istream& input_stream);
 	virtual BOOL exportLegacyStream(std::ostream& output_stream, BOOL include_asset_key = TRUE) const;
 
+	LLSD exportLLSD() const;
+	bool importLLSD(const LLSD& cat_data);
 	//--------------------------------------------------------------------
 	// Member Variables
 	//--------------------------------------------------------------------
diff --git a/indra/llinventory/llinventorysettings.cpp b/indra/llinventory/llinventorysettings.cpp
index fdad50e8d46b70fe5772d5d15df8088a7517014f..81485b3a975183050ade43ba87b4013af63a58e4 100644
--- a/indra/llinventory/llinventorysettings.cpp
+++ b/indra/llinventory/llinventorysettings.cpp
@@ -33,10 +33,6 @@
 #include "llsingleton.h"
 #include "llinvtranslationbrdg.h"
 
-//=========================================================================
-namespace {
-    LLTranslationBridge::ptr_t sTranslator;
-}
 
 //=========================================================================
 struct SettingsEntry : public LLDictionaryEntry
@@ -49,7 +45,7 @@ struct SettingsEntry : public LLDictionaryEntry
         mLabel(name),
         mIconName(iconName)
     {
-        std::string transdname = sTranslator->getString(mLabel);
+        std::string transdname = LLSettingsType::getInstance()->mTranslator->getString(mLabel);
         if (!transdname.empty())
         {
             mLabel = transdname;
@@ -84,6 +80,16 @@ void LLSettingsDictionary::initSingleton()
 
 //=========================================================================
 
+LLSettingsType::LLSettingsType(LLTranslationBridge::ptr_t &trans)
+{
+    mTranslator = trans;
+}
+
+LLSettingsType::~LLSettingsType()
+{
+    mTranslator.reset();
+}
+
 LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
 {
     return  (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
@@ -104,13 +110,3 @@ std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
         return getDefaultName(ST_INVALID);
     return entry->mDefaultNewName;
 }
-
-void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
-{
-    sTranslator = trans;
-}
-
-void LLSettingsType::cleanupClass()
-{
-    sTranslator.reset();
-}
diff --git a/indra/llinventory/llinventorysettings.h b/indra/llinventory/llinventorysettings.h
index 906540689c0dda7e51cd7b949c97830f4dfdccfa..6b6685d088d3d43b72e2a3c0c40d3e295125bb68 100644
--- a/indra/llinventory/llinventorysettings.h
+++ b/indra/llinventory/llinventorysettings.h
@@ -30,9 +30,15 @@
 
 #include "llinventorytype.h"
 #include "llinvtranslationbrdg.h"
+#include "llsingleton.h"
 
-class LLSettingsType
+class LLSettingsType : public LLParamSingleton<LLSettingsType>
 {
+    LLSINGLETON(LLSettingsType, LLTranslationBridge::ptr_t &trans);
+    ~LLSettingsType();
+
+    friend struct SettingsEntry;
+
 public:
     enum type_e
     {
@@ -48,8 +54,9 @@ class LLSettingsType
     static LLInventoryType::EIconName getIconName(type_e type);
     static std::string getDefaultName(type_e type);
 
-    static void initClass(LLTranslationBridge::ptr_t &trans);
-    static void cleanupClass();
+protected:
+
+    LLTranslationBridge::ptr_t mTranslator;
 };
 
 
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index e79b753514a874b49df8f22880154a40152109aa..0359d2f554ce9083133fb27d37163153a1c5b86f 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -565,148 +565,6 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b
 }
 
 
-//
-// File support
-//
-
-BOOL LLPermissions::importFile(LLFILE* fp)
-{
-	init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
-	const S32 BUFSIZE = 16384;
-
-	// *NOTE: Changing the buffer size will require changing the scanf
-	// calls below.
-	char buffer[BUFSIZE];	/* Flawfinder: ignore */
-	char keyword[256];	/* Flawfinder: ignore */
-	char valuestr[256];	/* Flawfinder: ignore */
-	char uuid_str[256];	/* Flawfinder: ignore */
-	U32 mask;
-
-	keyword[0]  = '\0';
-	valuestr[0] = '\0';
-
-	while (!feof(fp))
-	{
-		if (fgets(buffer, BUFSIZE, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-		
-		sscanf( /* Flawfinder: ignore */
-			buffer,
-			" %255s %255s",
-			keyword, valuestr);
-		if (!strcmp("{", keyword))
-		{
-			continue;
-		}
-		if (!strcmp("}",keyword))
-		{
-			break;
-		}
-		else if (!strcmp("creator_mask", keyword))
-		{
-			// legacy support for "creator" masks
-			sscanf(valuestr, "%x", &mask);
-			mMaskBase = mask;
-			fixFairUse();
-		}
-		else if (!strcmp("base_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskBase = mask;
-			//fixFairUse();
-		}
-		else if (!strcmp("owner_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskOwner = mask;
-		}
-		else if (!strcmp("group_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskGroup = mask;
-		}
-		else if (!strcmp("everyone_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskEveryone = mask;
-		}
-		else if (!strcmp("next_owner_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskNextOwner = mask;
-		}
-		else if (!strcmp("creator_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mCreator.set(uuid_str);
-		}
-		else if (!strcmp("owner_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mOwner.set(uuid_str);
-		}
-		else if (!strcmp("last_owner_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mLastOwner.set(uuid_str);
-		}
-		else if (!strcmp("group_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mGroup.set(uuid_str);
-		}
-		else if (!strcmp("group_owned", keyword))
-		{
-			sscanf(valuestr, "%d", &mask);
-			if(mask) mIsGroupOwned = true;
-			else mIsGroupOwned = false;
-		}
-		else
-		{
-			LL_INFOS() << "unknown keyword " << keyword << " in permissions import" << LL_ENDL;
-		}
-	}
-	fix();
-	return TRUE;
-}
-
-
-BOOL LLPermissions::exportFile(LLFILE* fp) const
-{
-	std::string uuid_str;
-
-	fprintf(fp, "\tpermissions 0\n");
-	fprintf(fp, "\t{\n");
-
-	fprintf(fp, "\t\tbase_mask\t%08x\n",		mMaskBase);
-	fprintf(fp, "\t\towner_mask\t%08x\n",		mMaskOwner);
-	fprintf(fp, "\t\tgroup_mask\t%08x\n",		mMaskGroup);
-	fprintf(fp, "\t\teveryone_mask\t%08x\n",	mMaskEveryone);
-	fprintf(fp, "\t\tnext_owner_mask\t%08x\n",	mMaskNextOwner);
-
-	mCreator.toString(uuid_str);
-	fprintf(fp, "\t\tcreator_id\t%s\n",			uuid_str.c_str());
-
-	mOwner.toString(uuid_str);
-	fprintf(fp, "\t\towner_id\t%s\n",			uuid_str.c_str());
-
-	mLastOwner.toString(uuid_str);
-	fprintf(fp, "\t\tlast_owner_id\t%s\n",		uuid_str.c_str());
-
-	mGroup.toString(uuid_str);
-	fprintf(fp, "\t\tgroup_id\t%s\n",			uuid_str.c_str());
-
-	if(mIsGroupOwned)
-	{
-		fprintf(fp, "\t\tgroup_owned\t1\n");
-	}
-	fprintf(fp,"\t}\n");
-	return TRUE;
-}
-
-
 BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
 {
 	init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index 89c66f6ebdc83aa531ec8ee810cf7839957f4b7c..27252f7b97da395caadc7f55687880369995728d 100644
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
@@ -311,10 +311,6 @@ class LLPermissions
 	void	packMessage(LLMessageSystem* msg) const;
 	void	unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
 
-	// Load/save support
-	BOOL	importFile(LLFILE* fp);
-	BOOL	exportFile(LLFILE* fp) const;
-
 	BOOL	importLegacyStream(std::istream& input_stream);
 	BOOL	exportLegacyStream(std::ostream& output_stream) const;
 
diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp
index 63e34d188ea046d9af0c70b62df05eff49f46d31..b7231ee239877388e5234d2ff825726d14a5fe9f 100644
--- a/indra/llinventory/llsaleinfo.cpp
+++ b/indra/llinventory/llsaleinfo.cpp
@@ -78,16 +78,6 @@ U32 LLSaleInfo::getCRC32() const
 	return rv;
 }
 
-
-BOOL LLSaleInfo::exportFile(LLFILE* fp) const
-{
-	fprintf(fp, "\tsale_info\t0\n\t{\n");
-	fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
-	fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice);
-	fprintf(fp,"\t}\n");
-	return TRUE;
-}
-
 BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
 {
 	output_stream << "\tsale_info\t0\n\t{\n";
@@ -129,69 +119,6 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
 	return true;
 }
 
-// Deleted LLSaleInfo::exportFileXML() and LLSaleInfo::importXML()
-// because I can't find any non-test code references to it. 2009-05-04 JC
-
-BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
-{
-	has_perm_mask = FALSE;
-
-	// *NOTE: Changing the buffer size will require changing the scanf
-	// calls below.
-	char buffer[MAX_STRING];	/* Flawfinder: ignore */
-	char keyword[MAX_STRING];	/* Flawfinder: ignore */
-	char valuestr[MAX_STRING];	/* Flawfinder: ignore */
-	BOOL success = TRUE;
-
-	keyword[0] = '\0';
-	valuestr[0] = '\0';
-	while(success && (!feof(fp)))
-	{
-		if (fgets(buffer, MAX_STRING, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-
-		sscanf(	/* Flawfinder: ignore */
-			buffer,
-			" %254s %254s",
-			keyword, valuestr);
-		if(!keyword[0])
-		{
-			continue;
-		}
-		if(0 == strcmp("{",keyword))
-		{
-			continue;
-		}
-		if(0 == strcmp("}", keyword))
-		{
-			break;
-		}
-		else if(0 == strcmp("sale_type", keyword))
-		{
-			mSaleType = lookup(valuestr);
-		}
-		else if(0 == strcmp("sale_price", keyword))
-		{
-			sscanf(valuestr, "%d", &mSalePrice);
-			mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
-		}
-		else if (!strcmp("perm_mask", keyword))
-		{
-			//LL_INFOS() << "found deprecated keyword perm_mask" << LL_ENDL;
-			has_perm_mask = TRUE;
-			sscanf(valuestr, "%x", &perm_mask);
-		}
-		else
-		{
-			LL_WARNS() << "unknown keyword '" << keyword
-					<< "' in sale info import" << LL_ENDL;
-		}
-	}
-	return success;
-}
-
 BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
 {
 	has_perm_mask = FALSE;
diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h
index 4e98ccf6ff4d2e3f88d223aa4f184bd99ad90e7b..3c8952838b02de58d64163229346e6926f4aacae 100644
--- a/indra/llinventory/llsaleinfo.h
+++ b/indra/llinventory/llsaleinfo.h
@@ -84,11 +84,6 @@ class LLSaleInfo
 	void setSalePrice(S32 price);
 	//void setNextOwnerPermMask(U32 mask)	{ mNextOwnerPermMask = mask; }
 
-
-	// file serialization
-	BOOL exportFile(LLFILE* fp) const;
-	BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask);
-
 	BOOL exportLegacyStream(std::ostream& output_stream) const;
 	LLSD asLLSD() const;
 	operator LLSD() const { return asLLSD(); }
diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h
index 1d118f07899d332d12b936a1f06e756018ed2656..f7a9d5b7cd262dc387ff62249c91057fc6222a18 100644
--- a/indra/llinventory/llsettingsbase.h
+++ b/indra/llinventory/llsettingsbase.h
@@ -359,7 +359,6 @@ class LLSettingsBase :
     virtual parammapping_t getParameterMap() const { return parammapping_t(); }
 
     LLSD        mSettings;
-    bool        mIsValid;
 
     LLSD        cloneSettings() const;
 
diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp
index 7b15552f24646d5be386f93471ffea8c829be067..e8b063bffe073e62129d4d929a16196b6146ecef 100644
--- a/indra/llinventory/tests/inventorymisc_test.cpp
+++ b/indra/llinventory/tests/inventorymisc_test.cpp
@@ -28,9 +28,9 @@
 
 #include "linden_common.h"
 #include "llsd.h"
+#include "llsdserialize.h"
 
 #include "../llinventory.h"
-
 #include "../test/lltut.h"
 
 
@@ -320,27 +320,39 @@ namespace tut
 	template<> template<>
 	void inventory_object::test<7>()
 	{
-		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
-		if(!fp)
+		std::string filename("linden_file.dat");
+		llofstream fileXML(filename.c_str());
+		if (!fileXML.is_open())
 		{
 			LL_ERRS() << "file could not be opened\n" << LL_ENDL;
 			return;
 		}
 			
 		LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
-		src1->exportFile(fp, TRUE);
-		fclose(fp);
+		fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl;
+		fileXML.close();
 
-		LLPointer<LLInventoryItem> src2 = new LLInventoryItem();	
-		fp = LLFile::fopen("linden_file.dat","r+");
-		if(!fp)
+		
+		LLPointer<LLInventoryItem> src2 = new LLInventoryItem();
+		llifstream file(filename.c_str());
+		if (!file.is_open())
 		{
 			LL_ERRS() << "file could not be opened\n" << LL_ENDL;
 			return;
 		}
-		
-		src2->importFile(fp);
-		fclose(fp);
+		std::string line;
+		LLPointer<LLSDParser> parser = new LLSDNotationParser();
+		std::getline(file, line);
+		LLSD s_item;
+		std::istringstream iss(line);
+		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+		{
+			LL_ERRS()<< "Parsing cache failed" << LL_ENDL;
+			return;
+		}
+		src2->fromLLSD(s_item);
+
+		file.close();
 		
 		ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
 		ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
@@ -457,27 +469,39 @@ namespace tut
 	template<> template<>
 	void inventory_object::test<13>()
 	{
-		LLFILE* fp = LLFile::fopen("linden_file.dat","w");
-		if(!fp)
+		std::string filename("linden_file.dat");
+		llofstream fileXML(filename.c_str());
+		if (!fileXML.is_open())
 		{
-			LL_ERRS() << "file coudnt be opened\n" << LL_ENDL;
+			LL_ERRS() << "file could not be opened\n" << LL_ENDL;
 			return;
 		}
-			
+
 		LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
-		src1->exportFile(fp, TRUE);
-		fclose(fp);
+		fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl;
+		fileXML.close();
 
-		LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();	
-		fp = LLFile::fopen("linden_file.dat","r");
-		if(!fp)
+		llifstream file(filename.c_str());
+		if (!file.is_open())
 		{
-			LL_ERRS() << "file coudnt be opened\n" << LL_ENDL;
+			LL_ERRS() << "file could not be opened\n" << LL_ENDL;
 			return;
 		}
-		
-		src2->importFile(fp);
-		fclose(fp);
+		std::string line;
+		LLPointer<LLSDParser> parser = new LLSDNotationParser();
+		std::getline(file, line);
+		LLSD s_item;
+		std::istringstream iss(line);
+		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+		{
+			LL_ERRS()<< "Parsing cache failed" << LL_ENDL;
+			return;
+		}
+
+		file.close();
+
+		LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
+		src2->importLLSD(s_item);
 
 		ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
 		ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 26684a4d9e93e5a5dfe3b7bfd7176ec6d3193e1c..a4fe3a2a8e1aba0aeff1b5cd7b936e06bef68504 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -360,7 +360,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
     }
 
     // The queue should never fill up.
-    LL_ERRS("CoProcMgr") << "Enqueue failed (" << unsigned(pushed) << ")" << LL_ENDL;
+    LL_ERRS("CoProcMgr") << "Enqueue into '" << name << "' failed (" << unsigned(pushed) << ")" << LL_ENDL;
     return {};                      // never executed, pacify the compiler
 }
 
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 58069afdf919553effc193bb10e52c0f9ef5e85c..6d51adc685fb0a1a2268942d8e01cf02b5ee2dd2 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -857,12 +857,12 @@ void LLPluginClassMedia::paste()
 }
 
 void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
-										 const std::string &user_data_path_cookies,
+										 const std::string &username,
 										 const std::string &user_data_path_cef_log)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
-	message.setValue("cache_path", user_data_path_cache);
-	message.setValue("cookies_path", user_data_path_cookies);
+    message.setValue("cache_path", user_data_path_cache);
+    message.setValue("username", username); // cef shares cache between users but creates user-based contexts
 	message.setValue("cef_log_file", user_data_path_cef_log);
 
 	bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 9d11ee0421d92f4b2efdaa28a8f800195be9aaa4..382f891e0c4132b4a0e2680f69d75818a61c5ff5 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -195,7 +195,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	bool	canPaste() const { return mCanPaste; };
 	
 	// These can be called before init(), and they will be queued and sent before the media init message.
-	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);
+	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log);
 	void	setLanguageCode(const std::string &language_code);
 	void	setPluginsEnabled(const bool enabled);
 	void	setJavascriptEnabled(const bool enabled);
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index c5304d2ccf69de9a7de96d5eaf341b634868f5be..d93ec8cf4b9417f1cae66953c597792d459217ae 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -225,6 +225,18 @@ void LLPluginProcessChild::idle(void)
 				}
 				setState(STATE_UNLOADED);
 			}
+
+            if (mInstance)
+            {
+                // Provide some time to the plugin
+                // example: CEF on "cleanup" sets shutdown request, but it still needs idle loop to actually shutdown
+                LLPluginMessage message("base", "idle");
+                message.setValueReal("time", PLUGIN_IDLE_SECONDS);
+                sendMessageToPlugin(message);
+
+                mInstance->idle();
+            }
+
 			break;
 
 		case STATE_UNLOADED:
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 498dfca1a36f708b823d2fd0bb76abbae707917a..604fb4e946718f71211aad905332394f2d805cf1 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2700,10 +2700,11 @@ LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_w
 }
 
 #if LL_WINDOWS
-// Expose desired use of high-performance graphics processor to Optimus driver
+// Expose desired use of high-performance graphics processor to Optimus driver and to AMD driver
 extern "C" 
-{ 
-    _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; 
+{
+    __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+    __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
 }
 #endif
 
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6a02cd9c19cdba0d8e60abe15218dbf6db9fb662..7d2b09ca4a742d469b4d809dec531c1d62ea34de 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1193,7 +1193,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
 		return true;
 	}
 
-	bool sucsess = true;
+	bool success = true;
 
 	mEmpty = true;
 
@@ -1215,9 +1215,9 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
 
 	if (!mMappedData)
 	{
-		sucsess = false;
+		success = false;
 	}
-	return sucsess;
+	return success;
 }
 
 bool LLVertexBuffer::createGLIndices(U32 size)
@@ -1232,7 +1232,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)
 		return true;
 	}
 
-	bool sucsess = true;
+	bool success = true;
 
 	mEmpty = true;
 
@@ -1257,9 +1257,9 @@ bool LLVertexBuffer::createGLIndices(U32 size)
 
 	if (!mMappedIndexData)
 	{
-		sucsess = false;
+		success = false;
 	}
-	return sucsess;
+	return success;
 }
 
 void LLVertexBuffer::destroyGLBuffer()
@@ -1306,7 +1306,7 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
 {
 	llassert(nverts >= 0);
 
-	bool sucsess = true;
+	bool success = true;
 
 	if (nverts > 65536)
 	{
@@ -1318,34 +1318,34 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
 
 	if (needed_size > mSize || needed_size <= mSize/2)
 	{
-		sucsess &= createGLBuffer(needed_size);
+		success &= createGLBuffer(needed_size);
 	}
 
 	sVertexCount -= mNumVerts;
 	mNumVerts = nverts;
 	sVertexCount += mNumVerts;
 
-	return sucsess;
+	return success;
 }
 
 bool LLVertexBuffer::updateNumIndices(S32 nindices)
 {
 	llassert(nindices >= 0);
 
-	bool sucsess = true;
+	bool success = true;
 
 	U32 needed_size = sizeof(U16) * nindices;
 
 	if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
 	{
-		sucsess &= createGLIndices(needed_size);
+		success &= createGLIndices(needed_size);
 	}
 
 	sIndexCount -= mNumIndices;
 	mNumIndices = nindices;
 	sIndexCount += mNumIndices;
 
-	return sucsess;
+	return success;
 }
 
 bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
@@ -1358,10 +1358,10 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
 		LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
 	}
 
-	bool sucsess = true;
+	bool success = true;
 
-	sucsess &= updateNumVerts(nverts);
-	sucsess &= updateNumIndices(nindices);
+	success &= updateNumVerts(nverts);
+	success &= updateNumIndices(nindices);
 	
 	if (create && (nverts || nindices))
 	{
@@ -1377,7 +1377,7 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
 		}
 	}
 
-	return sucsess;
+	return success;
 }
 
 static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 61a119800e3e483455a984d79aad1adbdc66433e..809d72208f0ba0bb546d2fff5b570bd5babf8f9e 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -55,6 +55,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
  , mTabComparator( NULL )
  , mNoVisibleTabsHelpText(NULL)
  , mNoVisibleTabsOrigString(params.no_visible_tabs_text.initial_value().asString())
+ , mSkipScrollToChild(false)
 {
 	initNoTabsWidget(params.no_matched_tabs_text);
 
@@ -659,7 +660,7 @@ void	LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
 // virtual
 void LLAccordionCtrl::onUpdateScrollToChild(const LLUICtrl *cntrl)
 {
-    if (mScrollbar && mScrollbar->getVisible())
+    if (mScrollbar && mScrollbar->getVisible() && !mSkipScrollToChild)
     {
         // same as scrollToShowRect
         LLRect rect;
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index b38a76d27f4d31d7e51cbbf49522c051490d612b..282825447245c0ce62781f5ed516510feb1ae469 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -138,6 +138,8 @@ class LLAccordionCtrl: public LLPanel
 
 	bool getFitParent() const {return mFitParent;}
 
+	void setSkipScrollToChild(bool skip) { mSkipScrollToChild = skip; }
+
 private:
 	void	initNoTabsWidget(const LLTextBox::Params& tb_params);
 	void	updateNoTabsHelpTextVisibility();
@@ -183,6 +185,8 @@ class LLAccordionCtrl: public LLPanel
 	F32				mAutoScrollRate;
 	LLTextBox*		mNoVisibleTabsHelpText;
 
+	bool			mSkipScrollToChild;
+
 	std::string		mNoMatchedTabsOrigString;
 	std::string		mNoVisibleTabsOrigString;
 
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index e718fcec46038d3306bd224f167490477bd94963..0c1dcc301bc7de197b7cad2909f91efeed3ed71e 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -342,7 +342,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
 void LLFolderView::filter( LLFolderViewFilter& filter )
 {
 	LL_RECORD_BLOCK_TIME(FTM_FILTER);
-    filter.resetTime(llclamp(LLUI::getInstance()->mSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
+    static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
+    static LLCachedControl<S32> filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
+    filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100));
 
     // Note: we filter the model, not the view
 	getViewModelItem()->filter(filter);
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9a1f7de73b7c1f0dc848440301c7784986ab0cff..1c6c7b1b3585d53a6b9e40e0049149f510b0f51a 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -122,6 +122,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 :	LLView(p),
 	mLabelWidth(0),
 	mLabelWidthDirty(false),
+    mSuffixNeedsRefresh(false),
     mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
 	mParentFolder( NULL ),
 	mIsSelected( FALSE ),
@@ -181,11 +182,25 @@ LLFolderViewItem::~LLFolderViewItem()
 
 BOOL LLFolderViewItem::postBuild()
 {
-	refresh();
+    LLFolderViewModelItem& vmi = *getViewModelItem();
+    // getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
+    // it also sets search strings so it requires a filter reset
+    mLabel = vmi.getDisplayName();
+    setToolTip(vmi.getName());
+
+    // Dirty the filter flag of the model from the view (CHUI-849)
+    vmi.dirtyFilter();
+
+    // Don't do full refresh on constructor if it is possible to avoid
+    // it significantly slows down bulk view creation.
+    // Todo: Ideally we need to move getDisplayName() out of constructor as well.
+    // Like: make a logic that will let filter update search string,
+    // while LLFolderViewItem::arrange() updates visual part
+    mSuffixNeedsRefresh = true;
+    mLabelWidthDirty = true;
 	return TRUE;
 }
 
-
 LLFolderView* LLFolderViewItem::getRoot()
 {
 	return mRoot;
@@ -280,24 +295,51 @@ BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation)
 
 void LLFolderViewItem::refresh()
 {
-	LLFolderViewModelItem& vmi = *getViewModelItem();
+    LLFolderViewModelItem& vmi = *getViewModelItem();
+
+    mLabel = vmi.getDisplayName();
+    setToolTip(vmi.getName());
+    // icons are slightly expensive to get, can be optimized
+    // see LLInventoryIcon::getIcon()
+    mIcon = vmi.getIcon();
+    mIconOpen = vmi.getIconOpen();
+    mIconOverlay = vmi.getIconOverlay();
 
-	mLabel = vmi.getDisplayName();
+    if (mRoot->useLabelSuffix())
+    {
+        // Very Expensive!
+        // Can do a number of expensive checks, like checking active motions, wearables or friend list
+        mLabelStyle = vmi.getLabelStyle();
+        mLabelSuffix = vmi.getLabelSuffix();
+    }
 
-	setToolTip(vmi.getName());
-	mIcon = vmi.getIcon();
-	mIconOpen = vmi.getIconOpen();
-	mIconOverlay = vmi.getIconOverlay();
+    // Dirty the filter flag of the model from the view (CHUI-849)
+    vmi.dirtyFilter();
+
+    mLabelWidthDirty = true;
+    mSuffixNeedsRefresh = false;
+}
+
+void LLFolderViewItem::refreshSuffix()
+{
+	LLFolderViewModelItem const* vmi = getViewModelItem();
+
+    // icons are slightly expensive to get, can be optimized
+    // see LLInventoryIcon::getIcon()
+	mIcon = vmi->getIcon();
+    mIconOpen = vmi->getIconOpen();
+    mIconOverlay = vmi->getIconOverlay();
 
 	if (mRoot->useLabelSuffix())
 	{
-		mLabelStyle = vmi.getLabelStyle();
-		mLabelSuffix = vmi.getLabelSuffix();
+        // Very Expensive!
+        // Can do a number of expensive checks, like checking active motions, wearables or friend list
+        mLabelStyle = vmi->getLabelStyle();
+        mLabelSuffix = vmi->getLabelSuffix();
 	}
 
-	mLabelWidthDirty = true;
-    // Dirty the filter flag of the model from the view (CHUI-849)
-	vmi.dirtyFilter();
+    mLabelWidthDirty = true;
+    mSuffixNeedsRefresh = false;
 }
 
 // Utility function for LLFolderView
@@ -348,6 +390,12 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
 		: 0;
 	if (mLabelWidthDirty)
 	{
+        if (mSuffixNeedsRefresh)
+        {
+            // Expensive. But despite refreshing label,
+            // it is purely visual, so it is fine to do at our laisure
+            refreshSuffix();
+        }
 		mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; 
 		mLabelWidthDirty = false;
 	}
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 61c39e0175fb0680cd37bab6e3d87c28f55a5673..da09d139e98e270e1ee1e4456fafacd4e5b0561c 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -95,6 +95,7 @@ class LLFolderViewItem : public LLView
 	LLPointer<LLFolderViewModelItem> mViewModelItem;
 	LLFontGL::StyleFlags		mLabelStyle;
 	std::string					mLabelSuffix;
+	bool						mSuffixNeedsRefresh; //suffix and icons
 	LLUIImagePtr				mIcon,
 								mIconOpen,
 								mIconOverlay;
@@ -266,8 +267,13 @@ class LLFolderViewItem : public LLView
 	virtual BOOL	passedFilter(S32 filter_generation = -1);
 	virtual BOOL	isPotentiallyVisible(S32 filter_generation = -1);
 
-	// refresh information from the object being viewed.
-	virtual void refresh();
+    // refresh information from the object being viewed.
+    // refreshes label, suffixes and sets icons. Expensive!
+    // Causes filter update
+    virtual void refresh();
+    // refreshes suffixes and sets icons. Expensive!
+    // Does not need filter update
+	virtual void refreshSuffix();
 
 	// LLView functionality
 	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index 3b45fb53a2183ebfa99ea982aeae816e929dbe8e..ea106b5fae098b7c9de657d96d918234b7b9a22d 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -48,7 +48,8 @@ std::string LLFolderViewModelCommon::getStatusText()
 
 void LLFolderViewModelCommon::filter()
 {
-    getFilter().resetTime(llclamp(LLUI::getInstance()->mSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
+    static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
+    getFilter().resetTime(llclamp(filter_visible(), 1, 100));
 	mFolderView->getViewModelItem()->filter(getFilter());
 }
 
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index f71a88c56e84d1e42e3131258e9a48dcb2db67f5..84a1539094426e163c063bc9e3ca53e0d004b7b0 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -285,17 +285,7 @@ class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 	typedef std::list<LLFolderViewModelItem*> child_list_t;
 
 	virtual void addChild(LLFolderViewModelItem* child) 
-	{ 
-		// Avoid duplicates: bail out if that child is already present in the list
-		// Note: this happens when models are created before views
-		child_list_t::const_iterator iter;
-		for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
-		{
-			if (child == *iter)
-			{
-				return;
-			}
-		}
+	{
 		mChildren.push_back(child);
 		child->setParent(this); 
 		dirtyFilter();
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
index 296ea0907931d230e428c7e1355c578413855cc1..ebd8ca0923aca13fb4b7eb62551759748537dabb 100644
--- a/indra/llui/llspellcheck.cpp
+++ b/indra/llui/llspellcheck.cpp
@@ -49,8 +49,6 @@ LLSpellChecker::settings_change_signal_t LLSpellChecker::sSettingsChangeSignal;
 LLSpellChecker::LLSpellChecker()
 	: mHunspell(NULL)
 {
-	// Load initial dictionary information
-	refreshDictionaryMap();
 }
 
 LLSpellChecker::~LLSpellChecker()
@@ -58,6 +56,12 @@ LLSpellChecker::~LLSpellChecker()
 	delete mHunspell;
 }
 
+void LLSpellChecker::initSingleton()
+{
+	// Load initial dictionary information
+	refreshDictionaryMap();
+}
+
 bool LLSpellChecker::checkSpelling(const std::string& word) const
 {
 	if ( (!mHunspell) || (word.length() < 3) || (0 != mHunspell->spell(word.c_str())) )
diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h
index f1964cc091940f6e03513f9143c79b22b5fc5e23..3da5e30955795bc5f11e7904b5226f504d0bf9c3 100644
--- a/indra/llui/llspellcheck.h
+++ b/indra/llui/llspellcheck.h
@@ -47,6 +47,7 @@ class LLSpellChecker : public LLSingleton<LLSpellChecker>
 protected:
 	void addToDictFile(const std::string& dict_path, const std::string& word);
 	void initHunspell(const std::string& dict_language);
+	void initSingleton();
 
 public:
 	typedef std::list<std::string> dict_list_t;
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 333d03f208da6ee44e86357946d133f40c534163..e6835f73fb461b34b69767ac42a7cc333e061610 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -454,13 +454,17 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
 }
 
 //
-// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
+// LLUrlEntrySeconlifeURL Describes *secondlife.com/ *lindenlab.com/ *secondlifegrid.net/ and *tilia-inc.com/ urls to substitute icon 'hand.png' before link
 //
 LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
 {                              
 	mPattern = boost::regex("((http://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com)"
 							"|"
-							"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?))"
+							"(http://([-\\w\\.]*\\.)?secondlifegrid\\.net)"
+							"|"
+							"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"
+							"|"
+							"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))"
 							"\\/\\S*",
 		boost::regex::perl|boost::regex::icase);
 	
@@ -495,12 +499,14 @@ std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
 }
 
 //
-// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com and *tilia-inc.com urls to substitute icon 'hand.png' before link
+// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com *lindenlab.com *secondlifegrid.net and *tilia-inc.com urls to substitute icon 'hand.png' before link
 //
 LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
   {
-	mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)",
-		boost::regex::perl|boost::regex::icase);
+	mPattern = boost::regex("https?://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(?!\\S)"
+							"|"
+							"https?://([-\\w\\.]*\\.)?secondlifegrid\\.net(?!\\S)",
+							boost::regex::perl|boost::regex::icase);
 
 	mIcon = "Hand";
 	mMenuName = "menu_url_http.xml";
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 7783505c27ef07c4b340981ad9638aaca96cce17..bef0ae76a8352d0f2e2748a1cadb1d156649da92 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -784,9 +784,6 @@ void LLWindowWin32::close()
 		resetDisplayResolution();
 	}
 
-	// Don't process events in our mainWindowProc any longer.
-	SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL);
-
 	// Make sure cursor is visible and we haven't mangled the clipping state.
 	showCursor();
 	setMouseClipping(FALSE);
@@ -832,16 +829,24 @@ void LLWindowWin32::close()
 
 	LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
 
-	// Make sure we don't leave a blank toolbar button.
-	ShowWindow(mWindowHandle, SW_HIDE);
+    if (IsWindow(mWindowHandle))
+    {
+        // Make sure we don't leave a blank toolbar button.
+        ShowWindow(mWindowHandle, SW_HIDE);
 
-	// This causes WM_DESTROY to be sent *immediately*
-	if (!destroy_window_handler(mWindowHandle))
-	{
-		OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
-			mCallbacks->translateString("MBShutdownErr"),
-			OSMB_OK);
-	}
+        // This causes WM_DESTROY to be sent *immediately*
+        if (!destroy_window_handler(mWindowHandle))
+        {
+            OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
+                mCallbacks->translateString("MBShutdownErr"),
+                OSMB_OK);
+        }
+    }
+    else
+    {
+        // Something killed the window while we were busy destroying gl or handle somehow got broken
+        LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
+    }
 
 	mWindowHandle = NULL;
 }
@@ -1133,7 +1138,10 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
         << " Height: " << (window_rect.bottom - window_rect.top)
         << " Fullscreen: " << mFullscreen
         << LL_ENDL;
-	DestroyWindow(mWindowHandle);
+    if (!destroy_window_handler(mWindowHandle))
+    {
+        LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;
+    }	
 	mWindowHandle = CreateWindowEx(dw_ex_style,
 		mWindowClassName,
 		mWindowTitle,
@@ -1453,8 +1461,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 			ReleaseDC (mWindowHandle, mhDC);						// Release The Device Context
 			mhDC = 0;											// Zero The Device Context
 		}
-		DestroyWindow (mWindowHandle);									// Destroy The Window
-		
+
+        // Destroy The Window
+        if (!destroy_window_handler(mWindowHandle))
+        {
+            LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL;
+        }		
 
 		mWindowHandle = CreateWindowEx(dw_ex_style,
 			mWindowClassName,
@@ -3397,7 +3409,10 @@ void LLSplashScreenWin32::hideImpl()
 {
 	if (mWindow)
 	{
-		DestroyWindow(mWindow);
+        if (!destroy_window_handler(mWindow))
+        {
+            LL_WARNS("Window") << "Failed to properly close splash screen window!" << LL_ENDL;
+        }
 		mWindow = NULL; 
 	}
 }
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index bc967c9bcaf487db130af3123e201b7bd04699f3..0bb62d79ff09c9e491d751333fbf69fb859ea09e 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -98,7 +98,9 @@ class MediaPluginCEF :
 	bool mCanCut;
 	bool mCanCopy;
 	bool mCanPaste;
+    std::string mRootCachePath;
 	std::string mCachePath;
+	std::string mContextCachePath;
 	std::string mCefLogFile;
 	bool mCefLogVerbose;
 	std::vector<std::string> mPickedFiles;
@@ -458,7 +460,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			}
 			else if (message_name == "cleanup")
 			{
-				mVolumeCatcher.setVolume(0); // Hack: masks CEF exit issues
 				mCEFLib->requestExit();
 			}
 			else if (message_name == "force_exit")
@@ -527,7 +528,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.accept_language_list = mHostLanguage;
 				settings.background_color = 0xffffffff;
 				settings.cache_enabled = true;
+				settings.root_cache_path = mRootCachePath;
 				settings.cache_path = mCachePath;
+				settings.context_cache_path = mContextCachePath;
 				settings.cookies_enabled = mCookiesEnabled;
 				settings.disable_gpu = mDisableGPU;
 #if LL_DARWIN
@@ -583,9 +586,25 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			else if (message_name == "set_user_data_path")
 			{
 				std::string user_data_path_cache = message_in.getValue("cache_path");
-				std::string user_data_path_cookies = message_in.getValue("cookies_path");
+				std::string subfolder = message_in.getValue("username");
 
-				mCachePath = user_data_path_cache + "cef_cache";
+				mRootCachePath = user_data_path_cache + "cef_cache";
+                if (!subfolder.empty())
+                {
+                    std::string delim;
+#if LL_WINDOWS
+                    // media plugin doesn't have access to gDirUtilp
+                    delim = "\\";
+#else
+                    delim = "/";
+#endif
+                    mCachePath = mRootCachePath + delim + subfolder;
+                }
+                else
+                {
+                    mCachePath = mRootCachePath;
+                }
+                mContextCachePath = ""; // disabled by ""
 				mCefLogFile = message_in.getValue("cef_log_file");
 				mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
 			}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a69e4e629dd240255bb227acb23a6da002b449f9..e47a04a1f94f194571385b05afb9c19983821cc0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -234,7 +234,7 @@ set(viewer_SOURCE_FILES
     llfloaterconversationpreview.cpp
     llfloaterdeleteprefpreset.cpp
     llfloaterdestinations.cpp
-	llfloaterdisplayname.cpp
+    llfloaterdisplayname.cpp
     llfloatereditextdaycycle.cpp
     llfloaterenvironmentadjust.cpp
     llfloaterevent.cpp
@@ -866,7 +866,7 @@ set(viewer_HEADER_FILES
     llfloaterconversationpreview.h
     llfloaterdeleteprefpreset.h
     llfloaterdestinations.h
-	llfloaterdisplayname.h
+    llfloaterdisplayname.h
     llfloatereditextdaycycle.h
     llfloaterenvironmentadjust.h
     llfloaterevent.h
@@ -2149,7 +2149,7 @@ if (DARWIN)
   set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
   set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
   set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
-  set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2019")
+  set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2020")
   set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
   set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLApplication")
 
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index e5a66bad386521830a492374c871201b97a4bbbe..d613169e8896c11271275886f09efa7954d4589f 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.11
+6.4.12
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 55e1d19f05f45a298f070bdc01c7108efe01d5bc..d133c6437b01f8559cf13639e27bf84013f9a3e6 100644
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -30,12 +30,6 @@
 #include "llhandle.h"
 
 #include "llaccountingcost.h"
-#include "httpcommon.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-#include "httprequest.h"
-#include "httpheaders.h"
-#include "httpoptions.h"
 
 //===============================================================================
 // An interface class for panels which display the parcel accounting information.
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 166c2d67c88b0fe81343793f31fdb5fa7d659b90..e7e9404dedf9ee3e1ed24b41d0e35531209675d7 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -137,6 +137,10 @@ class LLTeleportRequest
 	EStatus getStatus() const          {return mStatus;};
 	void    setStatus(EStatus pStatus) {mStatus = pStatus;};
 
+	static std::map<S32, std::string> sTeleportStatusName;
+	static const std::string& statusName(EStatus status);
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport() = 0;
@@ -148,12 +152,19 @@ class LLTeleportRequest
 	EStatus mStatus;
 };
 
+std::map<S32, std::string> LLTeleportRequest::sTeleportStatusName = { { kPending, "kPending" },
+																	  { kStarted, "kStarted" },
+																	  { kFailed, "kFailed" },
+																	  { kRestartPending, "kRestartPending"} };
+
 class LLTeleportRequestViaLandmark : public LLTeleportRequest
 {
 public:
 	LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
 	virtual ~LLTeleportRequestViaLandmark();
 
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport();
@@ -172,6 +183,8 @@ class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark
 	LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike);
 	virtual ~LLTeleportRequestViaLure();
 
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport();
@@ -189,6 +202,8 @@ class LLTeleportRequestViaLocation : public LLTeleportRequest
 	LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
 	virtual ~LLTeleportRequestViaLocation();
 
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport();
@@ -208,6 +223,8 @@ class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation
 	LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
 	virtual ~LLTeleportRequestViaLocationLookAt();
 
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport();
@@ -492,6 +509,8 @@ void LLAgent::init()
 void LLAgent::cleanup()
 {
 	mRegionp = NULL;
+    mTeleportRequest = NULL;
+    mTeleportCanceled = NULL;
 	if (mTeleportFinishedSlot.connected())
 	{
 		mTeleportFinishedSlot.disconnect();
@@ -867,7 +886,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 	if (mRegionp != regionp)
 	{
 
-		LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() << LL_ENDL;
+		LL_INFOS("AgentLocation","Teleport") << "Moving agent into region: handle " << regionp->getHandle() 
+											 << " id " << regionp->getRegionID()
+											 << " name " << regionp->getName()
+											 << " previous region "
+											 << (mRegionp ? mRegionp->getRegionID() : LLUUID::null)
+											 << LL_ENDL;
 		if (mRegionp)
 		{
 			// We've changed regions, we're now going to change our agent coordinate frame.
@@ -2629,6 +2653,7 @@ void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
 		else
 		{
 			mMaturityPreferenceNumRetries = 0;
+			LL_WARNS() << "Too many retries for maturity preference" << LL_ENDL;
 			reportPreferredMaturityError();
 		}
 	}
@@ -2680,6 +2705,7 @@ void LLAgent::reportPreferredMaturityError()
 	mIsMaturityRatingChangingDuringTeleport = false;
 	if (hasPendingTeleportRequest())
 	{
+		LL_WARNS("Teleport") << "Teleport failing due to preferred maturity error" << LL_ENDL;
 		setTeleportState(LLAgent::TELEPORT_NONE);
 	}
 
@@ -3775,7 +3801,7 @@ void LLAgent::clearVisualParams(void *data)
 // protected
 bool LLAgent::teleportCore(bool is_local)
 {
-    LL_INFOS("Teleport") << "In teleport core!" << LL_ENDL;
+    LL_DEBUGS("Teleport") << "In teleport core" << LL_ENDL;
 	if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))
 	{
 		LL_WARNS() << "Attempt to teleport when already teleporting." << LL_ENDL;
@@ -3841,11 +3867,13 @@ bool LLAgent::teleportCore(bool is_local)
 	add(LLStatViewer::TELEPORT, 1);
 	if (is_local)
 	{
+		LL_INFOS("Teleport") << "Setting teleport state to TELEPORT_LOCAL" << LL_ENDL;
 		gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL );
 	}
 	else
 	{
 		gTeleportDisplay = TRUE;
+		LL_INFOS("Teleport") << "Non-local, setting teleport state to TELEPORT_START" << LL_ENDL;
 		gAgent.setTeleportState( LLAgent::TELEPORT_START );
 
 		//release geometry from old location
@@ -3912,6 +3940,7 @@ void LLAgent::startTeleportRequest()
 		if  (!isMaturityPreferenceSyncedWithServer())
 		{
 			gTeleportDisplay = TRUE;
+			LL_INFOS("Teleport") << "Maturity preference not synced yet, setting teleport state to TELEPORT_PENDING" << LL_ENDL;
 			setTeleportState(TELEPORT_PENDING);
 		}
 		else
@@ -3955,10 +3984,19 @@ void LLAgent::handleTeleportFinished()
     {
         if (mRegionp->capabilitiesReceived())
         {
+			LL_DEBUGS("Teleport") << "capabilities have been received for region handle "
+								  << mRegionp->getHandle()
+								  << " id " << mRegionp->getRegionID()
+								  << ", calling onCapabilitiesReceivedAfterTeleport()"
+								  << LL_ENDL;
             onCapabilitiesReceivedAfterTeleport();
         }
         else
         {
+			LL_DEBUGS("Teleport") << "Capabilities not yet received for region handle "
+								  << mRegionp->getHandle()
+								  << " id " << mRegionp->getRegionID()
+								  << LL_ENDL;
             mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
         }
     }
@@ -3996,6 +4034,18 @@ void LLAgent::handleTeleportFailed()
 /*static*/
 void LLAgent::onCapabilitiesReceivedAfterTeleport()
 {
+	if (gAgent.getRegion())
+	{
+		LL_DEBUGS("Teleport") << "running after capabilities received callback has been triggered, agent region "
+							  << gAgent.getRegion()->getHandle()
+							  << " id " << gAgent.getRegion()->getRegionID()
+							  << " name " << gAgent.getRegion()->getName()
+							  << LL_ENDL;
+	}
+	else
+	{
+		LL_WARNS("Teleport") << "called when agent region is null!" << LL_ENDL;
+	}
 
     check_merchant_status();
 }
@@ -4009,8 +4059,8 @@ void LLAgent::teleportRequest(
 	LLViewerRegion* regionp = getRegion();
 	if (regionp && teleportCore(region_handle == regionp->getHandle()))
 	{
-		LL_INFOS("") << "TeleportLocationRequest: '" << region_handle << "':"
-					 << pos_local << LL_ENDL;
+		LL_INFOS("Teleport") << "Sending TeleportLocationRequest: '" << region_handle << "':"
+							 << pos_local << LL_ENDL;
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessage("TeleportLocationRequest");
 		msg->nextBlockFast(_PREHASH_AgentData);
@@ -4041,6 +4091,11 @@ void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
 	LLViewerRegion *regionp = getRegion();
 	if(regionp && teleportCore())
 	{
+		LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle()
+							 << " region id " << regionp->getRegionID()
+							 << " requested landmark id " << landmark_asset_id
+							 << LL_ENDL;
+
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessageFast(_PREHASH_TeleportLandmarkRequest);
 		msg->nextBlockFast(_PREHASH_Info);
@@ -4073,6 +4128,11 @@ void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
 			teleport_flags |= TELEPORT_FLAGS_VIA_LURE;
 		}
 
+		LL_INFOS("Teleport") << "Sending TeleportLureRequest."
+							 << " Current region handle " << regionp->getHandle()
+							 << " region id " << regionp->getRegionID()
+							 << " lure id " << lure_id
+							 << LL_ENDL;
 		// send the message
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessageFast(_PREHASH_TeleportLureRequest);
@@ -4095,6 +4155,8 @@ void LLAgent::teleportCancel()
 		LLViewerRegion* regionp = getRegion();
 		if(regionp)
 		{
+			LL_INFOS("Teleport") << "Sending TeleportCancel" << LL_ENDL;
+			
 			// send the message
 			LLMessageSystem* msg = gMessageSystem;
 			msg->newMessage("TeleportCancel");
@@ -4107,13 +4169,14 @@ void LLAgent::teleportCancel()
 	}
 	clearTeleportRequest();
 	gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
-	gPipeline.resetVertexBuffers();
+	gPipeline.resetVertexBuffers(); 
 }
 
 void LLAgent::restoreCanceledTeleportRequest()
 {
     if (mTeleportCanceled != NULL)
     {
+		LL_INFOS() << "Restoring canceled teleport request, setting state to TELEPORT_REQUESTED" << LL_ENDL;
         gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
         mTeleportRequest = mTeleportCanceled;
         mTeleportCanceled.reset();
@@ -4151,7 +4214,6 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
 	else if(regionp && 
 		teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
 	{
-		LL_WARNS() << "Using deprecated teleportlocationrequest." << LL_ENDL; 
 		// send the message
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessageFast(_PREHASH_TeleportLocationRequest);
@@ -4171,6 +4233,14 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
 		msg->addVector3Fast(_PREHASH_Position, pos);
 		pos.mV[VX] += 1;
 		msg->addVector3Fast(_PREHASH_LookAt, pos);
+
+		LL_WARNS("Teleport") << "Sending deprecated(?) TeleportLocationRequest."
+							 << " pos_global " << pos_global
+							 << " region_x " << region_x
+							 << " region_y " << region_y
+							 << " region_handle " << region_handle
+							 << LL_ENDL; 
+
 		sendReliableMessage();
 	}
 }
@@ -4212,7 +4282,11 @@ void LLAgent::setTeleportState(ETeleportState state)
             " for previously failed teleport.  Ignore!" << LL_ENDL;
         return;
     }
-    LL_DEBUGS("Teleport") << "Setting teleport state to " << state << " Previous state: " << mTeleportState << LL_ENDL;
+    LL_DEBUGS("Teleport") << "Setting teleport state to "
+						  << LLAgent::teleportStateName(state) << "(" << state << ")"
+						  << " Previous state: "
+						  << teleportStateName(mTeleportState) << "(" << mTeleportState << ")"
+						  << LL_ENDL;
 	mTeleportState = state;
 	if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
 	{
@@ -4549,6 +4623,34 @@ void LLAgent::observeFriends()
 	}
 }
 
+std::map<S32, std::string> LLAgent::sTeleportStateName = { { TELEPORT_NONE, "TELEPORT_NONE" },
+														   { TELEPORT_START, "TELEPORT_START" },
+														   { TELEPORT_REQUESTED, "TELEPORT_REQUESTED" },
+														   { TELEPORT_MOVING, "TELEPORT_MOVING" },
+														   { TELEPORT_START_ARRIVAL, "TELEPORT_START_ARRIVAL" },
+														   { TELEPORT_ARRIVING, "TELEPORT_ARRIVING" },
+														   { TELEPORT_LOCAL, "TELEPORT_LOCAL" },
+														   { TELEPORT_PENDING, "TELEPORT_PENDING" } };
+
+const std::string& LLAgent::teleportStateName(S32 state)
+{
+	static std::string invalid_state_str("INVALID");
+	auto iter = LLAgent::sTeleportStateName.find(state);
+	if (iter != LLAgent::sTeleportStateName.end())
+	{
+		return iter->second;
+	}
+	else
+	{
+		return invalid_state_str;
+	}
+}
+
+const std::string& LLAgent::getTeleportStateName() const
+{
+	return teleportStateName(getTeleportState());
+}
+
 void LLAgent::parseTeleportMessages(const std::string& xml_filename)
 {
 	LLXMLNodePtr root;
@@ -4672,40 +4774,70 @@ void LLTeleportRequest::restartTeleport()
 	llassert(0);
 }
 
+// TODO this enum -> name idiom should be in a common class rather than repeated various places.
+const std::string& LLTeleportRequest::statusName(EStatus status)
+{
+	static std::string invalid_status_str("INVALID");
+	auto iter = LLTeleportRequest::sTeleportStatusName.find(status);
+	if (iter != LLTeleportRequest::sTeleportStatusName.end())
+	{
+		return iter->second;
+	}
+	else
+	{
+		return invalid_status_str;
+	}
+}
+
+std::ostream& operator<<(std::ostream& os, const LLTeleportRequest& req)
+{
+	req.toOstream(os);
+	return os;
+}
+
+void LLTeleportRequest::toOstream(std::ostream& os) const
+{
+	os << "status " << statusName(mStatus) << "(" << mStatus << ")";
+}
+
 //-----------------------------------------------------------------------------
 // LLTeleportRequestViaLandmark
 //-----------------------------------------------------------------------------
-
 LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
 	: LLTeleportRequest(),
 	mLandmarkId(pLandmarkId)
 {
-    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created." << LL_ENDL;
+    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
 }
 
 LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
 {
-    LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark" << LL_ENDL;
+    LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
+}
+
+void LLTeleportRequestViaLandmark::toOstream(std::ostream& os) const
+{
+	os << "landmark " << mLandmarkId << " ";
+	LLTeleportRequest::toOstream(os);
 }
 
 bool LLTeleportRequestViaLandmark::canRestartTeleport()
 {
-    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::canRestartTeleport? -> true" << LL_ENDL;
+    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::canRestartTeleport? -> true, " << *this << LL_ENDL;
 	return true;
 }
 
 void LLTeleportRequestViaLandmark::startTeleport()
 {
-    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::startTeleport" << LL_ENDL;
+    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::startTeleport, " << *this << LL_ENDL;
 	gAgent.doTeleportViaLandmark(getLandmarkId());
 }
 
 void LLTeleportRequestViaLandmark::restartTeleport()
 {
-    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::restartTeleport" << LL_ENDL;
+    LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark::restartTeleport, " << *this << LL_ENDL;
 	gAgent.doTeleportViaLandmark(getLandmarkId());
 }
-
 //-----------------------------------------------------------------------------
 // LLTeleportRequestViaLure
 //-----------------------------------------------------------------------------
@@ -4722,6 +4854,12 @@ LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
     LL_INFOS("Teleport") << "~LLTeleportRequestViaLure" << LL_ENDL;
 }
 
+void LLTeleportRequestViaLure::toOstream(std::ostream& os) const
+{
+	os << "mIsLureGodLike " << (S32) mIsLureGodLike << " ";
+	LLTeleportRequestViaLandmark::toOstream(os);
+}
+
 bool LLTeleportRequestViaLure::canRestartTeleport()
 {
 	// stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions
@@ -4762,6 +4900,12 @@ LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
     LL_INFOS("Teleport") << "~LLTeleportRequestViaLocation" << LL_ENDL;
 }
 
+void LLTeleportRequestViaLocation::toOstream(std::ostream& os) const
+{
+	os << "mPosGlobal " << mPosGlobal << " ";
+	LLTeleportRequest::toOstream(os);
+}
+
 bool LLTeleportRequestViaLocation::canRestartTeleport()
 {
     LL_INFOS("Teleport") << "LLTeleportRequestViaLocation::canRestartTeleport -> true" << LL_ENDL;
@@ -4795,6 +4939,11 @@ LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
     LL_INFOS("Teleport") << "~LLTeleportRequestViaLocationLookAt" << LL_ENDL;
 }
 
+void LLTeleportRequestViaLocationLookAt::toOstream(std::ostream& os) const
+{
+	LLTeleportRequestViaLocation::toOstream(os);
+}
+
 bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
 {
     LL_INFOS("Teleport") << "LLTeleportRequestViaLocationLookAt::canRestartTeleport -> true" << LL_ENDL;
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 88cce0b9111e95155ce2a390ef6867dbbdf124df..f72378f65433528e3125c3ae05641694e1d258d4 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -47,20 +47,15 @@ extern const BOOL 	ANIMATE;
 extern const U8 	AGENT_STATE_TYPING;  // Typing indication
 extern const U8 	AGENT_STATE_EDITING; // Set when agent has objects selected
 
-class LLChat;
 class LLViewerRegion;
 class LLMotion;
-class LLToolset;
 class LLMessageSystem;
 class LLPermissions;
 class LLHost;
 class LLFriendObserver;
-class LLPickInfo;
-class LLViewerObject;
 class LLAgentDropGroupViewerNode;
 class LLAgentAccess;
 class LLSLURL;
-class LLPauseRequestHandle;
 class LLUIColor;
 class LLTeleportRequest;
 
@@ -91,8 +86,6 @@ struct LLGroupData
 
 class LLAgentListener;
 
-class LLAgentImpl;
-
 //------------------------------------------------------------------------
 // LLAgent
 //------------------------------------------------------------------------
@@ -619,6 +612,10 @@ class LLAgent : public LLOldEvents::LLObservable
 		TELEPORT_PENDING = 7
 	};
 
+	static std::map<S32, std::string> sTeleportStateName;
+	static const std::string& teleportStateName(S32);
+	const std::string& getTeleportStateName() const;
+
 public:
 	static void 	parseTeleportMessages(const std::string& xml_filename);
 	const void getTeleportSourceSLURL(LLSLURL& slurl) const;
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 2411f0f86d5d61c5652c064c30b2cc4d9045d84d..7f18ea6fe2ca45fe89264663b5c474e629c7ae09 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -881,13 +881,6 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback
 
 void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_remove_all, U32 index)
 {
-	if (gAgent.isTeen() &&
-		(type == LLWearableType::WT_UNDERSHIRT || type == LLWearableType::WT_UNDERPANTS))
-	{
-		// Can't take off underclothing in simple UI mode or on PG accounts
-		// TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx
-		return;
-	}
 	if (getWearableCount(type) == 0)
 	{
 		// no wearables to remove
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index ee49125711ab81e1483c32d8e15ab1bdce1df20a..005259bcb836affbf3d8b4647b0a136615fd8451 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -44,6 +44,10 @@
 const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3");
 const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3");
 
+std::list<AISAPI::ais_query_item_t> AISAPI::sPostponedQuery;
+
+const S32 MAX_SIMULTANEOUS_COROUTINES = 2048;
+
 //-------------------------------------------------------------------------
 /*static*/
 bool AISAPI::isAvailable()
@@ -366,9 +370,51 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t
 /*static*/
 void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc)
 {
+    LLCoprocedureManager &inst = LLCoprocedureManager::instance();
+    S32 pending_in_pool = inst.countPending("AIS");
     std::string procFullName = "AIS(" + procName + ")";
-    LLCoprocedureManager::instance().enqueueCoprocedure("AIS", procFullName, proc);
+    if (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES)
+    {
+        inst.enqueueCoprocedure("AIS", procFullName, proc);
+    }
+    else
+    {
+        // As I understand it, coroutines have built-in 'pending' pool
+        // but unfortunately it has limited size which inventory often goes over
+        // so this is a workaround to not overfill it.
+        if (sPostponedQuery.empty())
+        {
+            sPostponedQuery.push_back(ais_query_item_t(procFullName, proc));
+            gIdleCallbacks.addFunction(onIdle, NULL);
+        }
+        else
+        {
+            sPostponedQuery.push_back(ais_query_item_t(procFullName, proc));
+        }
+    }
+}
 
+/*static*/
+void AISAPI::onIdle(void *userdata)
+{
+    if (!sPostponedQuery.empty())
+    {
+        LLCoprocedureManager &inst = LLCoprocedureManager::instance();
+        S32 pending_in_pool = inst.countPending("AIS");
+        while (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES && !sPostponedQuery.empty())
+        {
+            ais_query_item_t &item = sPostponedQuery.front();
+            inst.enqueueCoprocedure("AIS", item.first, item.second);
+            sPostponedQuery.pop_front();
+            pending_in_pool++;
+        }
+    }
+    
+    if (sPostponedQuery.empty())
+    {
+        // Nothing to do anymore
+        gIdleCallbacks.deleteFunction(onIdle, NULL);
+    }
 }
 
 /*static*/
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index e97059014bd11fedf3847eb78041544de3d78cf9..856f3fc1802ff3569da436880ea689cdf0dee521 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -31,7 +31,6 @@
 #include <map>
 #include <set>
 #include <string>
-#include "llhttpretrypolicy.h"
 #include "llviewerinventory.h"
 #include "llcorehttputil.h"
 #include "llcoproceduremanager.h"
@@ -72,6 +71,7 @@ class AISAPI
         const std::string, LLSD, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t) > invokationFn_t;
 
     static void EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc);
+    static void onIdle(void *userdata); // launches postponed AIS commands
 
     static std::string getInvCap();
     static std::string getLibCap();
@@ -80,6 +80,8 @@ class AISAPI
         invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body, 
         completion_t callback, COMMAND_TYPE type);
 
+    typedef std::pair<std::string, LLCoprocedureManager::CoProcedure_t> ais_query_item_t;
+    static std::list<ais_query_item_t> sPostponedQuery;
 };
 
 class AISUpdate
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 168b8eb47a53bab0c943c7f86695d9bf6aa44ffd..e5c505501e326c782a0ff4039d3156aee3ec1b89 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3278,6 +3278,50 @@ void update_base_outfit_after_ordering()
 	bool copy_folder_links = false;
 	app_mgr.slamCategoryLinks(app_mgr.getCOF(), base_outfit_id, copy_folder_links, dirty_state_updater);
 
+    if (base_outfit_id.notNull())
+    {
+        LLIsValidItemLink collector;
+
+        LLInventoryModel::cat_array_t cof_cats;
+        LLInventoryModel::item_array_t cof_item_array;
+        gInventory.collectDescendentsIf(app_mgr.getCOF(), cof_cats, cof_item_array,
+            LLInventoryModel::EXCLUDE_TRASH, collector);
+
+        for (U32 i = 0; i < outfit_item_array.size(); ++i)
+        {
+            LLViewerInventoryItem* linked_item = outfit_item_array.at(i)->getLinkedItem();
+            if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+            {
+                outfit_item_array.erase(outfit_item_array.begin() + i);
+                break;
+            }
+        }
+
+        if (outfit_item_array.size() != cof_item_array.size())
+        {
+            return;
+        }
+
+        std::sort(cof_item_array.begin(), cof_item_array.end(), sort_by_linked_uuid);
+        std::sort(outfit_item_array.begin(), outfit_item_array.end(), sort_by_linked_uuid);
+
+        for (U32 i = 0; i < cof_item_array.size(); ++i)
+        {
+            LLViewerInventoryItem *cof_it = cof_item_array.at(i);
+            LLViewerInventoryItem *base_it = outfit_item_array.at(i);
+
+            if (cof_it->getActualDescription() != base_it->getActualDescription())
+            {
+                if (cof_it->getLinkedUUID() == base_it->getLinkedUUID())
+                {
+                    base_it->setDescription(cof_it->getActualDescription());
+                    gInventory.updateItem(base_it);
+                }
+            }
+        }
+        LLAppearanceMgr::getInstance()->updateIsDirty();
+    }
+
 }
 
 // Save COF changes - update the contents of the current base outfit
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 70b41a0a5faa2844101984a91d611d9d074f815c..515d6ffc1400f9339bccd742ced3662bbcd95d9c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -527,7 +527,8 @@ bool	create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
 
 	LLIconCtrl* icon;
 
-	if(gAgent.isInGroup(match_id, TRUE))
+	if( match->getMenuName() == "menu_url_group.xml" // See LLUrlEntryGroup constructor
+		|| gAgent.isInGroup(match_id, TRUE)) //This check seems unfiting, urls are either /agent or /group
 	{
 		LLGroupIconCtrl::Params icon_params;
 		icon_params.group_id = match_id;
@@ -605,8 +606,9 @@ static void settings_to_globals()
 static void settings_modify()
 {
 	LLRenderTarget::sUseFBO				= gSavedSettings.getBOOL("RenderDeferred");
+	LLPipeline::sRenderTransparentWater	= gSavedSettings.getBOOL("RenderTransparentWater");
 	LLPipeline::sRenderBump				= gSavedSettings.getBOOL("RenderObjectBump");
-	LLPipeline::sRenderDeferred		= LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+	LLPipeline::sRenderDeferred		= LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
 	LLVOSurfacePatch::sLODFactor		= gSavedSettings.getF32("RenderTerrainLODFactor");
 	LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
 	gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
@@ -781,7 +783,7 @@ bool LLAppViewer::init()
 
     // initialize the LLSettingsType translation bridge.
     LLTranslationBridge::ptr_t trans = std::make_shared<LLUITranslationBridge>();
-    LLSettingsType::initClass(trans);
+    LLSettingsType::initParamSingleton(trans);
 
 	// initialize SSE options
 	LLVector4a::initClass();
@@ -1024,13 +1026,27 @@ bool LLAppViewer::init()
 	{
 		// can't use an alert here since we're exiting and
 		// all hell breaks lose.
+		LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements");
 		OSMessageBox(
-			LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"),
+			details.getString(),
 			LLStringUtil::null,
 			OSMB_OK);
 		return 0;
 	}
 
+    // If we don't have the right shader requirements.
+    if (!gGLManager.mHasShaderObjects
+        || !gGLManager.mHasVertexShader
+        || !gGLManager.mHasFragmentShader)
+    {
+        LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedShaderRequirements");
+        OSMessageBox(
+            details.getString(),
+            LLStringUtil::null,
+            OSMB_OK);
+        return 0;
+    }
+
 	// Without SSE2 support we will crash almost immediately, warn here.
 	if (!gSysCPU.hasSSE2())
 	{
@@ -1501,8 +1517,10 @@ bool LLAppViewer::doFrame()
 			}
 
 			// yield cooperatively when not running as foreground window
-			if (   (gViewerWindow && !gViewerWindow->getWindow()->getVisible())
-					|| !gFocusMgr.getAppHasFocus())
+			// and when not quiting (causes trouble at mac's cleanup stage)
+			if (!LLApp::isExiting()
+				&& ((gViewerWindow && !gViewerWindow->getWindow()->getVisible())
+					|| !gFocusMgr.getAppHasFocus()))
 			{
 				// Sleep if we're not rendering, or the window is minimized.
 				static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40);
@@ -2100,8 +2118,6 @@ bool LLAppViewer::cleanup()
 
 	LLError::LLCallStacks::cleanup();
 
-	removeMarkerFiles();
-
 	// It's not at first obvious where, in this long sequence, a generic cleanup
 	// call OUGHT to go. So let's say this: as we migrate cleanup from
 	// explicit hand-placed calls into the generic mechanism, eventually
@@ -2109,14 +2125,12 @@ bool LLAppViewer::cleanup()
 	// still see above are calls that MUST happen before the generic cleanup
 	// kicks in.
 
-	// The logging subsystem depends on an LLSingleton. Any logging after
-	// LLSingletonBase::deleteAll() won't be recorded.
-	LL_INFOS() << "Goodbye!" << LL_ENDL;
-
 	// This calls every remaining LLSingleton's cleanupSingleton() and
 	// deleteSingleton() methods.
 	LLSingletonBase::deleteAll();
 
+    LL_INFOS() << "Goodbye!" << LL_ENDL;
+
 	removeDumpDir();
 
 	// return 0;
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
index a4ef762e8b1b07a02efb185426c766b31739cfd1..90aeff3032fa763f056121b56c48cfb521fda91c 100644
--- a/indra/newview/llattachmentsmgr.h
+++ b/indra/newview/llattachmentsmgr.h
@@ -30,8 +30,6 @@
 
 #include "llsingleton.h"
 
-class LLViewerInventoryItem;
-
 //--------------------------------------------------------------------------------
 // LLAttachmentsMgr
 // 
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index a1dacd1a270a201a13038786c9c71c489f221604..c510e86958a8ac87adf214cb10d87138aa00ed0a 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -31,7 +31,6 @@
 
 #include "lliconctrl.h"
 #include "llavatarpropertiesprocessor.h"
-#include "llviewermenu.h"
 
 class LLAvatarName;
 
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 36d18114aaec80f6d6a4484b9df94c5c8b41027e..b95cd685268440dac5ee986086ac18580edcfe12 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -30,7 +30,6 @@
 #include <boost/signals2.hpp>
 
 #include "llpanel.h"
-#include "lloutputmonitorctrl.h"
 #include "llbutton.h"
 #include "lltextbox.h"
 #include "llstyle.h"
@@ -38,6 +37,7 @@
 #include "llcallingcard.h" // for LLFriendObserver
 
 class LLAvatarIconCtrl;
+class LLOutputMonitorCtrl;
 class LLAvatarName;
 class LLIconCtrl;
 
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 54c6c985d6b5d2c040601916e13d7de7558ec262..3ab5c669c443e905c6d239345cdd3b3a687a5ae5 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -57,7 +57,6 @@
 #include "llinventorymodel.h"
 #include "llmultigesture.h"
 #include "llui.h"
-#include "llviewermenu.h"
 #include "lluictrlfactory.h"
 
 //
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 431a8c60be6de86f2f82ebfa6a27fcf876b954ac..2ba2c6d8b5b5668f4508f04d3af917acd1590495 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -64,6 +64,7 @@
 #include "llstring.h"
 #include "llurlaction.h"
 #include "llviewercontrol.h"
+#include "llviewermenu.h"
 #include "llviewerobjectlist.h"
 
 static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 4f42868f1a19a61df788ad4ab0cbc28bb7159dd3..1c22e055bb8f43a37fdefa970e5e4c95c7dcdcd8 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llchatitemscontainerctrl.h"
+#include "llchatmsgbox.h"
 #include "lltextbox.h"
 
 #include "llavataractions.h"
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index f66670ec8c83a91c3ac61fce643b925261906abb..ebff9ca298cb66fe69d95aa399a47b0eca25bc5e 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -28,12 +28,13 @@
 #define LL_LLCHATITEMSCONTAINERCTRL_H_
 
 #include "llchat.h"
-#include "llchatmsgbox.h"
 #include "llpanel.h"
 #include "llscrollbar.h"
 #include "llviewerchat.h"
 #include "lltoastpanel.h"
 
+class LLChatMsgBox;
+
 typedef enum e_show_item_header
 {
 	CHATITEMHEADER_SHOW_ONLY_NAME = 0,
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 8d89455cd480d2af7f09c71d86e0112ade8f00f0..0f187b0ecfb6713642448eae1cb670173c614e56 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -36,6 +36,7 @@
 #include "llsingleton.h"
 #include "llsyswellwindow.h"
 #include "llfloaternotificationstabbed.h"
+#include "llviewermenu.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
 static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 1caefd58abb8806e5fdd7d9f2a68d5205da7392b..b31981b235d597e1203aa892da78b9df6285dfe1 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -140,10 +140,31 @@ class CofAttachmentContextMenu : public CofContextMenu
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
+		registrar.add("Attachment.Touch", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
+		registrar.add("Attachment.Edit", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
 		registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 
+		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+		enable_registrar.add("Attachment.OnEnable", boost::bind(&CofAttachmentContextMenu::onEnable, this, _2));
+
 		return createFromFile("menu_cof_attachment.xml");
 	}
+
+	bool onEnable(const LLSD& userdata)
+	{
+		const std::string event_name = userdata.asString();
+
+		if ("touch" == event_name)
+		{
+			return (1 == mUUIDs.size()) && (enable_attachment_touch(mUUIDs.front()));
+		}
+		else if ("edit" == event_name)
+		{
+			return (1 == mUUIDs.size()) && (get_is_item_editable(mUUIDs.front()));
+		}
+
+		return true;
+	}
 };
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index 380fdccfa37ace92d649699b0472921d31d4dd24..a17cab486a77c4df75269be8f655956cacd6801c 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -36,7 +36,6 @@
 // Classes
 //
 class LLColor4;
-class LLFloaterColorPicker;
 
 class LLColorSwatchCtrl
 : public LLUICtrl
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index fe14bc081f2f6cbcf4473c4b75ac276b583018ae..06d959ba3cff3980c915933d746de0a380ed4837 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -402,23 +402,30 @@ bool LLCommandLineParser::parseCommandLineString(const std::string& str)
         }
     }
 
-    // Split the string content into tokens
-    const char* escape_chars = "\\";
-    const char* separator_chars = "\r\n ";
-    const char* quote_chars = "\"'";
-    boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
-    boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
     std::vector<std::string> tokens;
-    // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
-    for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
-        i != tok.end();
-        ++i)
+    try
     {
-        if(0 != i->size())
+        // Split the string content into tokens
+        const char* escape_chars = "\\";
+        const char* separator_chars = "\r\n ";
+        const char* quote_chars = "\"'";
+        boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
+        boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep);
+        // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
+        for (boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin();
+            i != tok.end();
+            ++i)
         {
-            tokens.push_back(*i);
+            if (0 != i->size())
+            {
+                tokens.push_back(*i);
+            }
         }
     }
+    catch (...)
+    {
+        CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("Unexpected crash while parsing: " << str));
+    }
 
     po::command_line_parser clp(tokens);
     return parseAndStoreResults(clp);
diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h
index 1b3d8f83a0bb0f3a3ab24fc315ff18270cb6963d..adb854875a1d31a04defe6b52cef10846846558e 100644
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
@@ -29,14 +29,11 @@
 
 #include "llinventory.h"
 #include "llviewerobject.h"
-#include "llvoinventorylistener.h"
 #include "lluuid.h"
 
 #include "llfloater.h"
 #include "llscrolllistctrl.h"
 
-#include "llviewerinventory.h"
-
 #include "llevents.h"
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index c2581368899430d3bb335e42126fc37f0399d1eb..4aa74a550cb65ee2ae14b9e9d52490dca16d7a7a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -92,6 +92,23 @@ LLConversationItem::~LLConversationItem()
 	}
 }
 
+//virtual
+void LLConversationItem::addChild(LLFolderViewModelItem* child)
+{
+    // Avoid duplicates: bail out if that child is already present in the list
+    // Note: this happens when models are created and 'parented' before views
+    // This is performance unfriendly, but conversation can addToFolder multiple times
+    child_list_t::const_iterator iter;
+    for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+    {
+        if (child == *iter)
+        {
+            return;
+        }
+    }
+    LLFolderViewModelItemCommon::addChild(child);
+}
+
 void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
 {
 	LLUUID session_id = (session ? session->getUUID() : LLUUID());
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 80385fad5f6a9ad4c6ad251ce8004bcaf86a2c97..30c74818648a1dc83a21453f2c35ec06e43b349b 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -96,6 +96,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
 	virtual BOOL isUpToDate() const { return TRUE; }
 	virtual bool hasChildren() const { return FALSE; }
+    virtual void addChild(LLFolderViewModelItem* child);
 
 	virtual bool potentiallyVisible() { return true; }
 	virtual bool filter( LLFolderViewFilter& filter) { return false; }
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 60a5204547d158b630a7723042de398a92b1a773..093e772abecbd7e85505005ef6de1d8bf3d66261 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -430,7 +430,7 @@ void LLConversationViewSession::refresh()
 	// Refresh the session view from its model data
 	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
 	vmi->resetRefresh();
-	
+
 	if (mSessionTitle)
 	{
 		mSessionTitle->setText(vmi->getDisplayName());
@@ -545,7 +545,9 @@ BOOL LLConversationViewParticipant::postBuild()
     }
 
     updateChildren();
-	return LLFolderViewItem::postBuild();
+	LLFolderViewItem::postBuild();
+    refresh();
+    return TRUE;
 }
 
 void LLConversationViewParticipant::draw()
@@ -619,7 +621,7 @@ void LLConversationViewParticipant::refresh()
 	
 	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
 	mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
-	
+
 	// Do the regular upstream refresh
 	LLFolderViewItem::refresh();
 }
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 420c250dfe7f8be5093611654eed960288f322f3..c5930c8a293aa2e6f761b6d8880173b7008ba1a6 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -34,6 +34,7 @@
 #include "lloutputmonitorctrl.h"
 
 class LLTextBox;
+class LLFloater;
 class LLFloaterIMContainer;
 class LLConversationViewSession;
 class LLConversationViewParticipant;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 6fc39f213e1bd6a79d3c9fa76eddfadc352c5249..87772d9eb689163efee6e8a9f0e25cca522c8170 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -38,7 +38,6 @@
 #include "lldrawable.h"
 #include "lldrawpoolbump.h"
 #include "llface.h"
-#include "llvolume.h"
 #include "llmeshrepository.h"
 #include "llsky.h"
 #include "llviewercamera.h"
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 7249f22555ee7c69807abc47de4219270663fa37..aa426cd785667714b3d2928a06bb0ea1ab658f88 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -163,7 +163,7 @@ void LLDrawPoolWater::render(S32 pass)
 	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
 
 	// See if we are rendering water as opaque or not
-	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
+	if (!LLPipeline::sRenderTransparentWater)
 	{
 		// render water for low end hardware
 		renderOpaqueLegacyWater();
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 342ee3ccf51ed19c6e230bf305e1f0f3af47cf72..e56ed92d9e93993af78c04e66176ee2cd3859545 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -806,6 +806,25 @@ const F32 LLEnvironment::SUN_DELTA_YAW(F_PI);   // 180deg
 const U32 LLEnvironment::DayInstance::NO_ANIMATE_SKY(0x01);
 const U32 LLEnvironment::DayInstance::NO_ANIMATE_WATER(0x02);
 
+std::string env_selection_to_string(LLEnvironment::EnvSelection_t sel)
+{
+#define RTNENUM(E) case LLEnvironment::E: return #E
+    switch (sel){
+        RTNENUM(ENV_EDIT);
+        RTNENUM(ENV_LOCAL);
+        RTNENUM(ENV_PUSH);
+        RTNENUM(ENV_PARCEL);
+        RTNENUM(ENV_REGION);
+        RTNENUM(ENV_DEFAULT);
+        RTNENUM(ENV_END);
+        RTNENUM(ENV_CURRENT);
+        RTNENUM(ENV_NONE);
+    default:
+        return llformat("Unknown(%d)", sel);
+    }
+#undef RTNENUM
+}
+
 
 //-------------------------------------------------------------------------
 LLEnvironment::LLEnvironment():
@@ -981,7 +1000,7 @@ bool LLEnvironment::canAgentUpdateRegionEnvironment() const
     if (gAgent.isGodlike())
         return true;
 
-    return gAgent.getRegion()->canManageEstate();
+    return gAgent.canManageEstate();
 }
 
 bool LLEnvironment::isExtendedEnvironmentEnabled() const
@@ -1037,7 +1056,8 @@ F32 LLEnvironment::getCamHeight() const
 
 F32 LLEnvironment::getWaterHeight() const
 {
-    return gAgent.getRegion()->getWaterHeight();
+    LLViewerRegion* cur_region = gAgent.getRegion();
+    return cur_region ? cur_region->getWaterHeight() : DEFAULT_WATER_HEIGHT;
 }
 
 bool LLEnvironment::getIsSunUp() const
@@ -1059,6 +1079,7 @@ void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, LL
 {
     mSelectedEnvironment = env;
     updateEnvironment(transition, forced);
+    LL_DEBUGS("ENVIRONMENT") << "Setting environment " << env_selection_to_string(env) << " with transition: " << transition << LL_ENDL;
 }
 
 bool LLEnvironment::hasEnvironment(LLEnvironment::EnvSelection_t env)
@@ -1095,11 +1116,13 @@ LLEnvironment::DayInstance::ptr_t LLEnvironment::getEnvironmentInstance(LLEnviro
 void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version)
 {
     if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
-    {   
-        LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+    {
+        LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
         return;
     }
 
+    logEnvironment(env, pday, env_version);
+
     DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
 
     environment->clear();
@@ -1116,7 +1139,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
 {
     if ((env < ENV_EDIT) || (env >= ENV_DEFAULT))
     {
-        LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection." << LL_ENDL;
+        LL_WARNS("ENVIRONMENT") << "Attempt to change invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
         return;
     }
 
@@ -1125,30 +1148,32 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
 
     if (fixed.first)
     {
+        logEnvironment(env, fixed.first, env_version);
         environment->setSky(fixed.first);
         environment->setFlags(DayInstance::NO_ANIMATE_SKY);
     }
     else if (!environment->getSky())
     {
+        LL_DEBUGS("ENVIRONMENT") << "Blank sky for " << env_selection_to_string(env) << ". Reusing environment for sky." << LL_ENDL;
         environment->setSky(mCurrentEnvironment->getSky());
         environment->setFlags(DayInstance::NO_ANIMATE_SKY);
     }
         
     if (fixed.second)
     {
+        logEnvironment(env, fixed.second, env_version);
         environment->setWater(fixed.second);
         environment->setFlags(DayInstance::NO_ANIMATE_WATER);
     }
     else if (!environment->getWater())
     {
+        LL_DEBUGS("ENVIRONMENT") << "Blank water for " << env_selection_to_string(env) << ". Reusing environment for water." << LL_ENDL;
         environment->setWater(mCurrentEnvironment->getWater());
         environment->setFlags(DayInstance::NO_ANIMATE_WATER);
     }
 
     if (!mSignalEnvChanged.empty())
         mSignalEnvChanged(env, env_version);
-
-    /*TODO: readjust environment*/
 }
 
 void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
@@ -1221,10 +1246,12 @@ void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
     if (!settings || status)
     {
         LLSD args;
-        args["DESC"] = asset_id.asString();
+        args["NAME"] = asset_id.asString();
         LLNotificationsUtil::add("FailedToFindSettings", args);
+        LL_DEBUGS("ENVIRONMENT") << "Failed to find settings for " << env_selection_to_string(env) << ", asset_id: " << asset_id << LL_ENDL;
         return;
     }
+    LL_DEBUGS("ENVIRONMENT") << "Loaded asset: " << asset_id << LL_ENDL;
 
     setEnvironment(env, settings);
     updateEnvironment(transition);
@@ -1238,19 +1265,48 @@ void LLEnvironment::clearEnvironment(LLEnvironment::EnvSelection_t env)
         return;
     }
 
+    LL_DEBUGS("ENVIRONMENT") << "Cleaning environment " << env_selection_to_string(env) << LL_ENDL;
+
     mEnvironments[env].reset();
 
     if (!mSignalEnvChanged.empty())
         mSignalEnvChanged(env, VERSION_CLEANUP);
+}
 
-    /*TODO: readjust environment*/
+void LLEnvironment::logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version)
+{
+    LL_DEBUGS("ENVIRONMENT") << "Setting Day environment " << env_selection_to_string(env) << " with version(update type): " << env_version << LL_NEWLINE;
+    // code between LL_DEBUGS and LL_ENDL won't execute unless log is enabled
+    if (settings)
+    {
+        LLUUID asset_id = settings->getAssetId();
+        if (asset_id.notNull())
+        {
+            LL_CONT << "Asset id: " << asset_id << LL_NEWLINE;
+        }
+
+        LLUUID id = settings->getId(); // Not in use?
+        if (id.notNull())
+        {
+            LL_CONT << "Settings id: " << id << LL_NEWLINE;
+        }
+
+        LL_CONT << "Name: " << settings->getName() << LL_NEWLINE
+            << "Type: " << settings->getSettingsType() << LL_NEWLINE
+            << "Flags: " << settings->getFlags(); // Not in use?
+    }
+    else
+    {
+        LL_CONT << "Empty settings!";
+    }
+    LL_CONT << LL_ENDL;
 }
 
 LLSettingsDay::ptr_t LLEnvironment::getEnvironmentDay(LLEnvironment::EnvSelection_t env)
 {
     if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
     {
-        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
         return LLSettingsDay::ptr_t();
     }
 
@@ -1266,7 +1322,7 @@ LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayLength(EnvSelection_t env
 {
     if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
     {
-        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
         return LLSettingsDay::Seconds(0);
     }
 
@@ -1282,7 +1338,7 @@ LLSettingsDay::Seconds LLEnvironment::getEnvironmentDayOffset(EnvSelection_t env
 {
     if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
     {
-        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
         return LLSettingsDay::Seconds(0);
     }
 
@@ -1325,7 +1381,7 @@ LLEnvironment::fixedEnvironment_t LLEnvironment::getEnvironmentFixed(LLEnvironme
 
     if ((env < ENV_EDIT) || (env > ENV_DEFAULT))
     {
-        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection." << LL_ENDL;
+        LL_WARNS("ENVIRONMENT") << "Attempt to retrieve invalid environment selection (" << env_selection_to_string(env) << ")." << LL_ENDL;
         return fixedEnvironment_t();
     }
 
@@ -2361,7 +2417,7 @@ void LLEnvironment::onSetExperienceEnvAssetLoaded(LLUUID experience_id, LLSettin
     if (!settings || status)
     {
         LLSD args;
-        args["DESC"] = experience_id.asString();
+        args["NAME"] = experience_id.asString();
         LLNotificationsUtil::add("FailedToFindSettings", args);
         return;
     }
@@ -3332,7 +3388,7 @@ namespace
                 return;
             }
 
-            LL_WARNS("PUSHENV") << "Underlying environment has changed (" << env << ")! Base env is type " << base_env << LL_ENDL;
+            LL_WARNS("PUSHENV", "ENVIRONMENT") << "Underlying environment has changed (" << env << ")! Base env is type " << base_env << LL_ENDL;
 
             LLEnvironment::DayInstance::ptr_t trans = std::make_shared<InjectedTransition>(std::static_pointer_cast<DayInjection>(shared_from_this()),
                 mBaseDayInstance->getSky(), mBaseDayInstance->getWater(), nextbase, LLEnvironment::TRANSITION_DEFAULT);
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index 91c4b851352d9928c5a1d9e899f137e8307af967..6ab0db75019f2471a56f1e1475f477efec4e774c 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -148,8 +148,11 @@ class LLEnvironment : public LLSingleton<LLEnvironment>
     void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
 
     void                        setSharedEnvironment();
-
     void                        clearEnvironment(EnvSelection_t env);
+
+    static void                 logEnvironment(EnvSelection_t env, const LLSettingsBase::ptr_t &settings, S32 env_version = NO_VERSION);
+
+
     LLSettingsDay::ptr_t        getEnvironmentDay(EnvSelection_t env);
     LLSettingsDay::Seconds      getEnvironmentDayLength(EnvSelection_t env);
     LLSettingsDay::Seconds      getEnvironmentDayOffset(EnvSelection_t env);
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index dd2baacb7ed287b44fd299089689398d3a7a424b..580a3f26103792a4f52cc63feed51a0e694324e7 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -84,7 +84,10 @@ BOOL LLFloaterConversationPreview::postBuild()
 		file = "chat";
 	}
 	mChatHistoryFileName = file;
-
+	if (mIsGroup && !LLStringUtil::endsWith(mChatHistoryFileName, GROUP_CHAT_SUFFIX))
+	{
+		mChatHistoryFileName += GROUP_CHAT_SUFFIX;
+	}
 	LLStringUtil::format_map_t args;
 	args["[NAME]"] = name;
 	std::string title = getString("Title", args);
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index ea22043de88a567dccdc38c440a595f7b041eff2..a7c2cbbeaa2d5e2f3c4948e63eb35821f97bff71 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -1498,7 +1498,7 @@ void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::pt
     if (!settings || status)
     {
         LLSD args;
-        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
+        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
         LLNotificationsUtil::add("FailedToFindSettings", args);
         closeFloater();
         return;
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index 37e162b2493c60ddad7eb646ab1d70fceda33fed..cd8e0a48e7c170f185be2ad12ce9839f1c2d97c1 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -346,7 +346,7 @@ void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::p
     if (!settings || status)
     {
         LLSD args;
-        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : "Unknown";
+        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
         LLNotificationsUtil::add("FailedToFindSettings", args);
         closeFloater();
         return;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 82ce97f311f2c027edfa29c1ae829a1f6b5a8f52..2a05f82f940cdecede72b1fdb6f3fd3d7e2d3c2d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -54,6 +54,7 @@
 #include "llcallbacklist.h"
 #include "llworld.h"
 #include "llsdserialize.h"
+#include "llviewermenu.h" // is_agent_mappable
 #include "llviewerobjectlist.h"
 #include "boost/foreach.hpp"
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 96094dcf1464d1c326b01ed98b1910e2e711640d..1cd8841bb4db709c6ac66ab5f4378731ce197ece 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1322,9 +1322,11 @@ void LLFloaterPreference::refreshEnabledState()
 
 	//Deferred/SSAO/Shadows
 	BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+	BOOL transparent_water = LLFeatureManager::getInstance()->isFeatureAvailable("RenderTransparentWater") && gSavedSettings.getBOOL("RenderTransparentWater");
 	BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
 	BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
 						bumpshiny &&
+						transparent_water &&
 						shaders && 
 						gGLManager.mHasFramebufferObject &&
 						gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -1347,7 +1349,10 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
 	ctrl_reflections->setEnabled(reflections);
 	reflections_text->setEnabled(reflections);
-	
+
+    // Transparent Water
+    LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
+
 	// Bump & Shiny	
 	LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
 	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
@@ -1398,6 +1403,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     
     BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
                         ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
+                        ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
                         gGLManager.mHasFramebufferObject &&
                         gSavedSettings.getBOOL("RenderAvatarVP") &&
                         (ctrl_wind_light->get()) ? TRUE : FALSE;
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index bcba14d63d107cec93b113a321fd57628724234b..8221b0a637043c9a389104e81f1e4b84c180be3a 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -34,6 +34,7 @@
 
 class LLSpinCtrl;
 class LLSnapshotLivePreview;
+class LLToolset;
 
 class LLFloaterSnapshotBase : public LLFloater
 {
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index fce945df6c4849d594dfe19b5b8f7d94971edeff..97e99297cfe60e11ee9f5b51d0c61c7075e18369 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -33,7 +33,6 @@
 #define LL_LLFLOATERWORLDMAP_H
 
 #include "llfloater.h"
-#include "llhudtext.h"
 #include "llmapimagetype.h"
 #include "lltracker.h"
 #include "llslurl.h"
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 2f7a98c86cf9de08a916fd41d2316871aa5bd2a2..ce128519eae15c04f8cd8df817007c22c834775d 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -102,7 +102,7 @@ class LLHUDObject : public LLRefCount
 	static void sortObjects();
 
 	LLHUDObject(const U8 type);
-	~LLHUDObject();
+	virtual ~LLHUDObject();
 
 	virtual void render() = 0;
 	virtual void renderForTimer() {};
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 82824861a9f901e52d870149ff1c9af6882bfd5b..72d28a3d44e66f16296eae1a629f1ecaec90798b 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -565,7 +565,10 @@ S32 LLHUDText::getMaxLines()
 
 void LLHUDText::markDead()
 {
-	sTextObjects.erase(LLPointer<LLHUDText>(this));
+    // make sure we have at least one pointer
+    // till the end of the function
+	LLPointer<LLHUDText> ptr(this);
+	sTextObjects.erase(ptr);
 	LLHUDObject::markDead();
 }
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 539d80532ca17afc658bcdd6fd0a3263078377d0..e9aaca13eb106dccd50c4da11a850f8d249ae1b1 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -6379,6 +6379,14 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 	{
 		LLAppearanceMgr::instance().wearItemOnAvatar(mUUID, true, false); // Don't replace if adding.
 	}
+	else if ("touch" == action)
+	{
+		handle_attachment_touch(mUUID);
+	}
+	else if ("edit" == action)
+	{
+		handle_attachment_edit(mUUID);
+	}
 	else if (isRemoveAction(action))
 	{
 		LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
@@ -6529,6 +6537,19 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 			if( get_is_item_worn( mUUID ) )
 			{
 				items.push_back(std::string("Wearable And Object Separator"));
+
+				items.push_back(std::string("Attachment Touch"));
+				if ( ((flags & FIRST_SELECTED_ITEM) == 0) || !enable_attachment_touch(mUUID) )
+				{
+					disabled_items.push_back(std::string("Attachment Touch"));
+				}
+
+				items.push_back(std::string("Wearable Edit"));
+				if ( ((flags & FIRST_SELECTED_ITEM) == 0) || !get_is_item_editable(mUUID) )
+				{
+					disabled_items.push_back(std::string("Wearable Edit"));
+				}
+
 				items.push_back(std::string("Detach From Yourself"));
 			}
 			else if (!isItemInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing() && !isCOFFolder())
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 646d92b9e15e34241f3abfbb574248bc89644444..d069aa32232c52c28d9eb778a99779ef92ccd26c 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -78,6 +78,7 @@
 #include "lltooldraganddrop.h"
 #include "lltrans.h"
 #include "lluictrlfactory.h"
+#include "llviewermenu.h"
 #include "llviewermessage.h"
 #include "llviewerfoldertype.h"
 #include "llviewerobjectlist.h"
@@ -655,6 +656,50 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
 	return TRUE;
 }
 
+bool get_is_item_editable(const LLUUID& inv_item_id)
+{
+	if (const LLInventoryItem* inv_item = gInventory.getLinkedItem(inv_item_id))
+	{
+		switch (inv_item->getType())
+		{
+			case LLAssetType::AT_BODYPART:
+			case LLAssetType::AT_CLOTHING:
+				return gAgentWearables.isWearableModifiable(inv_item_id);
+			case LLAssetType::AT_OBJECT:
+				return true;
+			default:
+                return false;;
+		}
+	}
+	return gAgentAvatarp->getWornAttachment(inv_item_id) != nullptr;
+}
+
+void handle_item_edit(const LLUUID& inv_item_id)
+{
+	if (get_is_item_editable(inv_item_id))
+	{
+		if (const LLInventoryItem* inv_item = gInventory.getLinkedItem(inv_item_id))
+		{
+			switch (inv_item->getType())
+			{
+				case LLAssetType::AT_BODYPART:
+				case LLAssetType::AT_CLOTHING:
+					LLAgentWearables::editWearable(inv_item_id);
+					break;
+				case LLAssetType::AT_OBJECT:
+					handle_attachment_edit(inv_item_id);
+					break;
+				default:
+					break;
+			}
+		}
+		else
+		{
+			handle_attachment_edit(inv_item_id);
+		}
+	}
+}
+
 BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
 {
 	// NOTE: This function doesn't check the folder's children.
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index fd106bc2d855b3730b34b22159673ea0a4968087..04eb9623726d3623b2eb177f619f2168cdceddbc 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -53,6 +53,10 @@ BOOL get_can_item_be_worn(const LLUUID& id);
 
 BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id);
 
+// Performs the appropiate edit action (if one exists) for this item
+bool get_is_item_editable(const LLUUID& inv_item_id);
+void handle_item_edit(const LLUUID& inv_item_id);
+
 BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
 
 BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 17e80dca891d3b792126955b858460231225a5ef..28db6a58084dee8de33250f8087e22c9c78d9bf3 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -56,6 +56,7 @@
 #include "llcallbacklist.h"
 #include "llvoavatarself.h"
 #include "llgesturemgr.h"
+#include "llsdserialize.h"
 #include "llsdutil.h"
 #include "bufferarray.h"
 #include "bufferstream.h"
@@ -76,8 +77,8 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
 ///----------------------------------------------------------------------------
 
 //BOOL decompress_file(const char* src_filename, const char* dst_filename);
-static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv";
-static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv";
+static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv.llsd";
+static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv.llsd";
 static const char * const LOG_INV("Inventory");
 
 struct InventoryIDPtrLess
@@ -678,17 +679,59 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv
 
     LLUUID categoryId = result["folder_id"].asUUID();
 
-    // Add the category to the internal representation
-    LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
-        result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
-        result["name"].asString(), gAgent.getID());
+    LLViewerInventoryCategory* folderp = gInventory.getCategory(categoryId);
+    if (!folderp)
+    {
+        // Add the category to the internal representation
+        LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
+            result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+            result["name"].asString(), gAgent.getID());
 
-    cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
-    cat->setDescendentCount(0);
-    LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
-    
-    accountForUpdate(update);
-    updateCategory(cat);
+        LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+        accountForUpdate(update);
+
+        cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
+        cat->setDescendentCount(0);
+        updateCategory(cat);
+    }
+    else
+    {
+        // bulk processing was faster than coroutine (coro request->processBulkUpdateInventory->coro response)
+        // category already exists, but needs an update
+        if (folderp->getVersion() != LLViewerInventoryCategory::VERSION_INITIAL
+            || folderp->getDescendentCount() != LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
+        {
+            LL_WARNS() << "Inventory desync on folder creation. Newly created folder already has descendants or got a version.\n"
+                << "Name: " << folderp->getName()
+                << " Id: " << folderp->getUUID()
+                << " Version: " << folderp->getVersion()
+                << " Descendants: " << folderp->getDescendentCount()
+                << LL_ENDL;
+        }
+        // Recreate category with correct values
+        // Creating it anew just simplifies figuring out needed change-masks
+        // and making all needed updates, see updateCategory
+        LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
+            result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+            result["name"].asString(), gAgent.getID());
+
+        if (folderp->getParentUUID() != cat->getParentUUID())
+        {
+            LL_WARNS() << "Inventory desync on folder creation. Newly created folder has wrong parent.\n"
+                << "Name: " << folderp->getName()
+                << " Id: " << folderp->getUUID()
+                << " Expected parent: " << cat->getParentUUID()
+                << " Actual parent: " << folderp->getParentUUID()
+                << LL_ENDL;
+            LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+            accountForUpdate(update);
+        }
+        // else: Do not update parent, parent is already aware of the change. See processBulkUpdateInventory
+
+        cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
+        cat->setDescendentCount(0);
+        updateCategory(cat);
+    }
 
     if (callback)
     {
@@ -903,16 +946,29 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 		LLUUID new_parent_id = item->getParentUUID();
 		bool update_parent_on_server = false;
 
-		if (new_parent_id.isNull())
+		if (new_parent_id.isNull() && !LLApp::isExiting())
 		{
-			// item with null parent will end in random location and then in Lost&Found,
-			// either move to default folder as if it is new item or don't move at all
-			LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
-				<< " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
-				<< ". New name: " << item->getName()
-				<< "." << LL_ENDL;
-			new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
-			update_parent_on_server = true;
+            if (old_parent_id.isNull())
+            {
+                // Item with null parent will end in random location and then in Lost&Found,
+                // either move to default folder as if it is new item or don't move at all
+                LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
+                                  << " to null folder. Moving to Lost&Found. Old item name: " << old_item->getName()
+                                  << ". New name: " << item->getName()
+                                  << "." << LL_ENDL;
+                new_parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+                update_parent_on_server = true;
+            }
+            else
+            {
+                // Probably not the best way to handle this, we might encounter real case of 'lost&found' at some point
+                LL_WARNS(LOG_INV) << "Update attempts to reparent item " << item->getUUID()
+                                  << " to null folder. Old parent not null. Moving to old parent. Old item name: " << old_item->getName()
+                                  << ". New name: " << item->getName()
+                                  << "." << LL_ENDL;
+                new_parent_id = old_parent_id;
+                update_parent_on_server = true;
+            }
 		}
 
 		if(old_parent_id != new_parent_id)
@@ -2648,29 +2704,37 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
 {
 	if(filename.empty())
 	{
-		LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL;
+		LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL;
 		return false;
 	}
-	LL_INFOS(LOG_INV) << "LLInventoryModel::loadFromFile(" << filename << ")" << LL_ENDL;
-	LLFILE* file = LLFile::fopen(filename, "rb");		/*Flawfinder: ignore*/
-	if(!file)
+	LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL;
+
+	llifstream file(filename.c_str());
+
+	if (!file.is_open())
 	{
 		LL_INFOS(LOG_INV) << "unable to load inventory from: " << filename << LL_ENDL;
 		return false;
 	}
-	// *NOTE: This buffer size is hard coded into scanf() below.
-	char buffer[MAX_STRING];		/*Flawfinder: ignore*/
-	char keyword[MAX_STRING];		/*Flawfinder: ignore*/
-	char value[MAX_STRING];			/*Flawfinder: ignore*/
-	is_cache_obsolete = true;  		// Obsolete until proven current
-	while(!feof(file) && fgets(buffer, MAX_STRING, file)) 
+
+	is_cache_obsolete = true; // Obsolete until proven current
+
+	std::string line;
+	LLPointer<LLSDParser> parser = new LLSDNotationParser();
+	while (std::getline(file, line)) 
 	{
-		sscanf(buffer, " %126s %126s", keyword, value);	/* Flawfinder: ignore */
-		if(0 == strcmp("inv_cache_version", keyword))
+		LLSD s_item;
+		std::istringstream iss(line);
+		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+		{
+			LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL;
+			break;
+		}
+
+		if (s_item.has("inv_cache_version"))
 		{
-			S32 version;
-			int succ = sscanf(value,"%d",&version);
-			if ((1 == succ) && (version == sCurrentInvCacheVersion))
+			S32 version = s_item["inv_cache_version"].asInteger();
+			if (version == sCurrentInvCacheVersion)
 			{
 				// Cache is up to date
 				is_cache_obsolete = false;
@@ -2678,43 +2742,33 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
 			}
 			else
 			{
-				// Cache is out of date
+				LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL;
 				break;
 			}
 		}
-		else if(0 == strcmp("inv_category", keyword))
+		else if (s_item.has("cat_id"))
 		{
 			if (is_cache_obsolete)
 				break;
-			
+
 			LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
-			if(inv_cat->importFileLocal(file))
+			if(inv_cat->importLLSD(s_item))
 			{
 				categories.push_back(inv_cat);
 			}
-			else
-			{
-				LL_WARNS(LOG_INV) << "loadInventoryFromFile().  Ignoring invalid inventory category: " << inv_cat->getName() << LL_ENDL;
-				//delete inv_cat; // automatic when inv_cat is reassigned or destroyed
-			}
 		}
-		else if(0 == strcmp("inv_item", keyword))
+		else if (s_item.has("item_id"))
 		{
 			if (is_cache_obsolete)
 				break;
 
 			LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
-			if( inv_item->importFileLocal(file) )
+			if( inv_item->fromLLSD(s_item) )
 			{
-				// *FIX: Need a better solution, this prevents the
-				// application from freezing, but breaks inventory
-				// caching.
 				if(inv_item->getUUID().isNull())
 				{
-					//delete inv_item; // automatic when inv_cat is reassigned or destroyed
 					LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: "
-									  << inv_item->getName() << LL_ENDL;
-						
+						<< inv_item->getName() << LL_ENDL;
 				}
 				else
 				{
@@ -2727,62 +2781,63 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
 						items.push_back(inv_item);
 					}
 				}
-			}
-			else
-			{
-				LL_WARNS(LOG_INV) << "loadInventoryFromFile().  Ignoring invalid inventory item: " << inv_item->getName() << LL_ENDL;
-				//delete inv_item; // automatic when inv_cat is reassigned or destroyed
-			}
-		}
-		else
-		{
-			LL_WARNS(LOG_INV) << "Unknown token in inventory file '" << keyword << "'"
-							  << LL_ENDL;
+			}	
 		}
 	}
-	fclose(file);
-	if (is_cache_obsolete)
-		return false;
-	return true;
+
+	file.close();
+
+	return !is_cache_obsolete;	
 }
 
 // static
 bool LLInventoryModel::saveToFile(const std::string& filename,
-								  const cat_array_t& categories,
-								  const item_array_t& items)
+	const cat_array_t& categories,
+	const item_array_t& items)
 {
-	if(filename.empty())
+	if (filename.empty())
 	{
 		LL_ERRS(LOG_INV) << "Filename is Null!" << LL_ENDL;
 		return false;
 	}
-	LL_INFOS(LOG_INV) << "LLInventoryModel::saveToFile(" << filename << ")" << LL_ENDL;
-	LLFILE* file = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/
-	if(!file)
+
+	LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL;
+
+	llofstream fileXML(filename.c_str());
+	if (!fileXML.is_open())
 	{
 		LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL;
 		return false;
 	}
 
-	fprintf(file, "\tinv_cache_version\t%d\n",sCurrentInvCacheVersion);
+	LLSD cache_ver;
+	cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
+
+	fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
+
 	S32 count = categories.size();
+	S32 cat_count = 0;
 	S32 i;
 	for(i = 0; i < count; ++i)
 	{
 		LLViewerInventoryCategory* cat = categories[i];
 		if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
 		{
-			cat->exportFileLocal(file);
+			fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
+			cat_count++;
 		}
 	}
 
-	count = items.size();
-	for(i = 0; i < count; ++i)
+	S32 it_count = items.size();
+	for(i = 0; i < it_count; ++i)
 	{
-		items[i]->exportFile(file);
+		fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
 	}
 
-	fclose(file);
+	fileXML.close();
+
+	LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
+
 	return true;
 }
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 7ff1006773bc8c2cd97d044a97346089f8207d79..f96750fb0b1c397f7b1cc09cc66d6ec858cda19d 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -146,7 +146,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mCompletionObserver(NULL),
 	mScroller(NULL),
 	mSortOrderSetting(p.sort_order_setting),
-	mInventory(p.inventory),
+	mInventory(p.inventory), //inventory("", &gInventory)
 	mAcceptsDragAndDrop(p.accepts_drag_and_drop),
 	mAllowMultiSelect(p.allow_multi_select),
 	mAllowDrag(p.allow_drag),
@@ -512,7 +512,18 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
 			view_item->destroyView();
 			removeItemID(idp);
 		}
-		view_item = buildNewViews(item_id);
+
+        LLInventoryObject const* objectp = mInventory->getObject(item_id);
+        if (objectp)
+        {
+            // providing NULL directly avoids unnessesary getItemByID calls
+            view_item = buildNewViews(item_id, objectp, NULL);
+        }
+        else
+        {
+            view_item = NULL;
+        }
+
 		viewmodel_item = 
 			static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
 		view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
@@ -555,7 +566,13 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
 		if (model_item && !view_item)
 		{
 			// Add the UI element for this item.
-			buildNewViews(item_id);
+            LLInventoryObject const* objectp = mInventory->getObject(item_id);
+            if (objectp)
+            {
+                // providing NULL directly avoids unnessesary getItemByID calls
+                buildNewViews(item_id, objectp, NULL);
+            }
+
 			// Select any newly created object that has the auto rename at top of folder root set.
 			if(mFolderRoot.get()->getRoot()->needsAutoRename())
 			{
@@ -852,7 +869,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 
 LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 {
-    LLInventoryObject const* objectp = gInventory.getObject(id);
+    LLInventoryObject const* objectp = mInventory->getObject(id);
     return buildNewViews(id, objectp);
 }
 
@@ -862,11 +879,43 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
     {
         return NULL;
     }
+    if (!typedViewsFilter(id, objectp))
+    {
+        // if certain types are not allowed permanently, no reason to create views
+        return NULL;
+    }
+
+    const LLUUID &parent_id = objectp->getParentUUID();
     LLFolderViewItem* folder_view_item = getItemByID(id);
+    LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+    return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *folder_view_item)
+{
+    if (!objectp)
+    {
+        return NULL;
+    }
+    if (!typedViewsFilter(id, objectp))
+    {
+        // if certain types are not allowed permanently, no reason to create views
+        return NULL;
+    }
 
     const LLUUID &parent_id = objectp->getParentUUID();
-	LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
-  		
+    LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+    return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder);
+}
+
+LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
+                                                  const LLUUID& parent_id,
+                                                  LLInventoryObject const* objectp,
+                                                  LLFolderViewItem *folder_view_item,
+                                                  LLFolderViewFolder *parent_folder)
+{
     // Force the creation of an extra root level folder item if required by the inventory panel (default is "false")
     bool allow_drop = true;
     bool create_root = false;
@@ -887,7 +936,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
   		{
 			if (objectp->getType() <= LLAssetType::AT_NONE)
 			{
-				LL_WARNS() << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
+				LL_WARNS() << "LLInventoryPanel::buildViewsTree called with invalid objectp->mType : "
 					<< ((S32)objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
 					<< LL_ENDL;
 				return NULL;
@@ -896,7 +945,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
 			if (objectp->getType() >= LLAssetType::AT_COUNT)
   			{
 				// Example: Happens when we add assets of new, not yet supported type to library
-				LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : "
+				LL_DEBUGS() << "LLInventoryPanel::buildViewsTree called with unknown objectp->mType : "
 				<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
 				<< LL_ENDL;
 
@@ -973,26 +1022,52 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO
 		LLViewerInventoryCategory::cat_array_t* categories;
 		LLViewerInventoryItem::item_array_t* items;
 		mInventory->lockDirectDescendentArrays(id, categories, items);
-		
+
+        LLFolderViewFolder *parentp = dynamic_cast<LLFolderViewFolder*>(folder_view_item);
+
 		if(categories)
-		{
+        {
+            bool has_folders = parentp->getFoldersCount() > 0;
 			for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin();
 				 cat_iter != categories->end();
 				 ++cat_iter)
 			{
 				const LLViewerInventoryCategory* cat = (*cat_iter);
-				buildNewViews(cat->getUUID());
+                if (typedViewsFilter(cat->getUUID(), cat))
+                {
+                    if (has_folders)
+                    {
+                        // This can be optimized: we don't need to call getItemByID()
+                        // each time, especially since content is growing, we can just
+                        // iter over copy of mItemMap in some way
+                        LLFolderViewItem* view_itemp = getItemByID(cat->getUUID());
+                        buildViewsTree(cat->getUUID(), id, cat, view_itemp, parentp);
+                    }
+                    else
+                    {
+                        buildViewsTree(cat->getUUID(), id, cat, NULL, parentp);
+                    }
+                }
 			}
 		}
 		
 		if(items)
-		{
+        {
 			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
 				 item_iter != items->end();
 				 ++item_iter)
 			{
 				const LLViewerInventoryItem* item = (*item_iter);
-				buildNewViews(item->getUUID());
+                if (typedViewsFilter(item->getUUID(), item))
+                {
+
+                    // This can be optimized: we don't need to call getItemByID()
+                    // each time, especially since content is growing, we can just
+                    // iter over copy of mItemMap in some way
+                    LLFolderViewItem* view_itemp = getItemByID(item->getUUID());
+                    buildViewsTree(item->getUUID(), id, item, view_itemp, parentp);
+                }
+
 			}
 		}
 		mInventory->unlockDirectDescendentArrays(id);
@@ -1789,21 +1864,20 @@ BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, B
     return result;
 }
 
-LLFolderViewItem* LLAssetFilteredInventoryPanel::buildNewViews(const LLUUID& id)
+/*virtual*/
+bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp)
 {
-    LLInventoryObject const* objectp = gInventory.getObject(id);
-
     if (!objectp)
     {
-        return NULL;
+        return false;
     }
 
     if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
     {
-        return NULL;
+        return false;
     }
 
-    return LLInventoryPanel::buildNewViews(id, objectp);
+    return true;
 }
 
 void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, const LLInventoryObject* model_item)
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index b51dc17cddc8aba5d7f3056459e75515cb070e5b..c202333f452fb05b68747e4cfa01564fefa276e0 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -325,8 +325,15 @@ class LLInventoryPanel : public LLPanel
 	static LLUIColor			sLibraryColor;
 	static LLUIColor			sLinkColor;
 	
-	virtual LLFolderViewItem*	buildNewViews(const LLUUID& id);
-	LLFolderViewItem*			buildNewViews(const LLUUID& id, LLInventoryObject const* objectp);
+	LLFolderViewItem*			buildNewViews(const LLUUID& id);
+    LLFolderViewItem*			buildNewViews(const LLUUID& id,
+                                              LLInventoryObject const* objectp);
+    LLFolderViewItem*			buildNewViews(const LLUUID& id,
+                                              LLInventoryObject const* objectp,
+                                              LLFolderViewItem *target_view);
+    // if certain types are not allowed, no reason to create views
+    virtual bool				typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) { return true; }
+
 	virtual void				itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item);
 	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
 	
@@ -334,10 +341,39 @@ class LLInventoryPanel : public LLPanel
 	virtual LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop);
 	virtual LLFolderViewItem*	createFolderViewItem(LLInvFVBridge * bridge);
 private:
+    // buildViewsTree does not include some checks and is meant
+    // for recursive use, use buildNewViews() for first call
+    LLFolderViewItem*			buildViewsTree(const LLUUID& id,
+                                              const LLUUID& parent_id,
+                                              LLInventoryObject const* objectp,
+                                              LLFolderViewItem *target_view,
+                                              LLFolderViewFolder *parent_folder_view);
+
 	bool				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
 	bool				mViewsInitialized; // Views have been generated
 };
 
+
+class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
+{
+public:
+    struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+    {};
+
+    void initFromParams(const Params& p);
+    bool isSelectionRemovable() { return false; }
+    void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
+
+protected:
+    LLInventoryFavoriteItemsPanel(const Params& params);
+    ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); }
+    void updateFavoritesRootFolder();
+
+    boost::signals2::connection mFolderChangedSignal;
+    boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
+    friend class LLUICtrlFactory;
+};
+
 /************************************************************************/
 /* Asset Pre-Filtered Inventory Panel related class                     */
 /* Exchanges filter's flexibility for speed of generation and           */
@@ -369,7 +405,7 @@ class LLAssetFilteredInventoryPanel : public LLInventoryPanel
         std::string& tooltip_msg) override;
 
 protected:
-    /*virtual*/ LLFolderViewItem*	buildNewViews(const LLUUID& id) override;
+    /*virtual*/ bool				typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) override;
     /*virtual*/ void				itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
 
 private:
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 1fc70cd6d6438888396b837192ee2ffc961d9e16..b4236c406b8b79ce85f2d7ecfcce2ee07c3d8430 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -40,8 +40,8 @@
 LLLandmarkList gLandmarkList;
 
 // number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size,
-// which is 4096, to not overfill the pool if user has more than 4K of landmarks,
-// and low number helps with not flooding server with requests
+// which is 4096, to not overfill the pool if user has more than 4K of landmarks
+// and it should leave some space for other potential simultaneous asset request
 const S32 MAX_SIMULTANEOUS_REQUESTS = 512;
 
 
@@ -98,7 +98,11 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
 
         if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
         {
-            // Postpone download till queu is emptier
+            // Workarounds for corutines pending list size limit:
+            // Postpone download till queue is emptier.
+            // Coroutines have own built in 'pending' list, but unfortunately
+            // it is too small compared to potential amount of landmarks
+            // or assets.
             mWaitList.insert(asset_uuid);
             return NULL;
         }
@@ -176,17 +180,27 @@ void LLLandmarkList::processGetAssetReply(
         // todo: this should clean mLoadedCallbackMap!
 	}
 
-    if (!gLandmarkList.mWaitList.empty())
+    // getAssetData can fire callback immediately, causing
+    // a recursion which is suboptimal for very large wait list.
+    // 'scheduling' indicates that we are inside request and
+    // shouldn't be launching more requests.
+    static bool scheduling = false;
+    if (!scheduling && !gLandmarkList.mWaitList.empty())
     {
-        // start new download from wait list
-        landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
-        LLUUID asset_uuid = *iter;
-        gLandmarkList.mWaitList.erase(iter);
-        gAssetStorage->getAssetData(asset_uuid,
-            LLAssetType::AT_LANDMARK,
-            LLLandmarkList::processGetAssetReply,
-            NULL);
-        gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+        scheduling = true;
+        while (!gLandmarkList.mWaitList.empty() && gLandmarkList.mRequestedList.size() < MAX_SIMULTANEOUS_REQUESTS)
+        {
+            // start new download from wait list
+            landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
+            LLUUID asset_uuid = *iter;
+            gLandmarkList.mWaitList.erase(iter);
+            gAssetStorage->getAssetData(asset_uuid,
+                LLAssetType::AT_LANDMARK,
+                LLLandmarkList::processGetAssetReply,
+                NULL);
+            gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+        }
+        scheduling = false;
     }
 }
 
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 354f5a453bb3d336ffdb1ba7fcd2dae99ecf0790..415781bc27fcf0f0d76025883edac8e437c09fa8 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -133,6 +133,16 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
 	messages.back()[LL_IM_TEXT] = im_text;
 }
 
+std::string remove_utf8_bom(const char* buf)
+{
+	std::string res(buf);
+	if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF)
+	{
+		res.erase(0, 3);
+	}
+	return res;
+}
+
 class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 {
 	LLSINGLETON(LLLogChatTimeScanner);
@@ -417,7 +427,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 			continue;
 		}
 
-		std::string line(buffer);
+		std::string line(remove_utf8_bom(buffer));
 
 		//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
 		if (' ' == line[0])
@@ -805,7 +815,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
 		{
 			//matching a timestamp
 			boost::match_results<std::string::const_iterator> matches;
-			if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
+			if (boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
 			{
 				result = true;
 			}
@@ -1126,7 +1136,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
 			firstline = FALSE;
 			continue;
 		}
-		std::string line(buffer);
+		std::string line(remove_utf8_bom(buffer));
 
 		//updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
 		if (' ' == line[0])
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index b63dabe93c2803e3eb1d604ab48a443348d77c44..3e8731dfe61871079505ac7ed3eb9f2cbfbec255 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -99,7 +99,7 @@
 //     locking actions.  In particular, the following operations
 //     on LLMeshRepository are very averse to any stalls:
 //     * loadMesh
-//     * getMeshHeader (For structural details, see:
+//     * search in mMeshHeader (For structural details, see:
 //       http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format)
 //     * notifyLoadedMeshes
 //     * getSkinInfo
@@ -1911,6 +1911,12 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
 			{
 				LLMutexLock lock(mMutex);
 				mLoadedQ.push(mesh);
+				// LLPointer is not thread safe, since we added this pointer into
+				// threaded list, make sure counter gets decreased inside mutex lock
+				// and won't affect mLoadedQ processing
+				volume = NULL;
+				// might be good idea to turn mesh into pointer to avoid making a copy
+				mesh.mVolume = NULL;
 			}
 			return MESH_OK;
 		}
@@ -2863,12 +2869,12 @@ void LLMeshRepoThread::notifyLoadedMeshes()
 			mMutex->unlock();
 			break;
 		}
-		LoadedMesh mesh = mLoadedQ.front();
+		LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point
 		mLoadedQ.pop();
 		mMutex->unlock();
 		
 		update_metrics = true;
-		if (mesh.mVolume && mesh.mVolume->getNumVolumeFaces() > 0)
+		if (mesh.mVolume->getNumVolumeFaces() > 0)
 		{
 			gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
 		}
@@ -3213,7 +3219,6 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 			header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
 			header = iter->second;
 		}
-		gMeshRepo.mThread->mHeaderMutex->unlock();
 
 		if (header_bytes > 0
 			&& !header.has("404")
@@ -3234,7 +3239,10 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 			lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
 			lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
 
-			S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
+            // Do not unlock mutex untill we are done with LLSD.
+            // LLSD is smart and can work like smart pointer, is not thread safe.
+            gMeshRepo.mThread->mHeaderMutex->unlock();
+
 			S32 bytes = lod_bytes + header_bytes; 
 
 		
@@ -3270,6 +3278,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 		{
 			LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
 
+			gMeshRepo.mThread->mHeaderMutex->unlock();
+
 			// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
 			LLMutexLock lock(gMeshRepo.mThread->mMutex);
 			for (int i(0); i < 4; ++i)
@@ -4139,42 +4149,42 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
 
 bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
 {
-	LLSD mesh = mThread->getMeshHeader(mesh_id);
-	if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
-	{
-		return true;
-	}
-
-	LLModel::Decomposition* decomp = getDecomposition(mesh_id);
-	if (decomp && !decomp->mHull.empty())
-	{
-		return true;
-	}
+    if (mesh_id.isNull())
+    {
+        return false;
+    }
 
-	return false;
-}
+    if (mThread->hasPhysicsShapeInHeader(mesh_id))
+    {
+        return true;
+    }
 
-LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
-{
-	LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
+    LLModel::Decomposition* decomp = getDecomposition(mesh_id);
+    if (decomp && !decomp->mHull.empty())
+    {
+        return true;
+    }
 
-	return mThread->getMeshHeader(mesh_id);
+    return false;
 }
 
-LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
+bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
 {
-	static LLSD dummy_ret;
-	if (mesh_id.notNull())
-	{
-		LLMutexLock lock(mHeaderMutex);
-		mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
-		if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
-		{
-			return iter->second;
-		}
-	}
+    LLMutexLock lock(mHeaderMutex);
+    if (mMeshHeaderSize[mesh_id] > 0)
+    {
+        mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+        if (iter != mMeshHeader.end())
+        {
+            LLSD &mesh = iter->second;
+            if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+            {
+                return true;
+            }
+        }
+    }
 
-	return dummy_ret;
+    return false;
 }
 
 
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 9a627dabcbe5b36e08c3b7be77ec31aa6e82c688..81e49cb1d8d6390e6ff439f96c3431fa72d92172 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -343,7 +343,7 @@ class LLMeshRepoThread : public LLThread
 	bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
-	LLSD& getMeshHeader(const LLUUID& mesh_id);
+	bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
 
 	void notifyLoadedMeshes();
 	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -595,9 +595,6 @@ class LLMeshRepository
 	
 	bool meshUploadEnabled();
 	bool meshRezEnabled();
-	
-
-	LLSD& getMeshHeader(const LLUUID& mesh_id);
 
 	void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
                      bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index d60d1d748efe103ca12e4bf4fc6e4c18f0a21db8..a9e80ab5da107dcd7ea1ae10c3edaf030561c50a 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -245,6 +245,12 @@ LLModelPreview::~LLModelPreview()
     {
         mModelLoader->shutdown();
     }
+
+    if (mPreviewAvatar)
+    {
+        mPreviewAvatar->markDead();
+        mPreviewAvatar = NULL;
+    }
 }
 
 U32 LLModelPreview::calcResourceCost()
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 06bb886ae8a563825cd21367d89519344063c519..6751c25fb995ded9deb3521996de1f6e132e4b96 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -39,6 +39,7 @@
 #include "llagent.h"
 #include "llagentui.h"
 #include "lllandmarkactions.h"
+#include "llparcel.h"
 #include "llslurl.h"
 #include "llviewerinventory.h"
 #include "llviewerparcelmgr.h"
@@ -77,7 +78,7 @@ BOOL LLPanelLandmarkInfo::postBuild()
 	mCreator = getChild<LLTextBox>("creator");
 	mCreated = getChild<LLTextBox>("created");
 
-	mLandmarkTitle = getChild<LLTextBox>("title_value");
+	mLandmarkTitle = getChild<LLLineEditor>("title_value");
 	mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
 	mNotesEditor = getChild<LLTextEditor>("notes_editor");
 	mFolderCombo = getChild<LLComboBox>("folder_combo");
@@ -113,6 +114,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
 	landmark_info_panel->setVisible(type == LANDMARK);
 
 	getChild<LLTextBox>("folder_label")->setVisible(is_info_type_create_landmark);
+    getChild<LLButton>("edit_btn")->setVisible(!is_info_type_create_landmark);
 	mFolderCombo->setVisible(is_info_type_create_landmark);
 
 	switch(type)
@@ -126,13 +128,10 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
 			mNotesEditor->setEnabled(TRUE);
 
 			LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
-			std::string name = parcel_mgr->getAgentParcelName();
+			LLParcel* parcel = parcel_mgr->getAgentParcel();
+			std::string name = parcel->getName();
 			LLVector3 agent_pos = gAgent.getPositionAgent();
 			
-			std::string desc;
-			LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_FULL, agent_pos);
-			mNotesEditor->setText(desc);			
-
 			if (name.empty())
 			{
 				S32 region_x = ll_round(agent_pos.mV[VX]);
@@ -147,6 +146,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
 				}
 				else
 				{
+					std::string desc;
 					LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
 					region_name = desc;
 				}
@@ -159,6 +159,25 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
 				mLandmarkTitleEditor->setText(name);
 			}
 
+            LLUUID owner_id = parcel->getOwnerID();
+            if (owner_id.notNull())
+            {
+                if (parcel->getIsGroupOwned())
+                {
+                    std::string owner_name = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
+                    mParcelOwner->setText(owner_name);
+                }
+                else
+                {
+                    std::string owner_name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
+                    mParcelOwner->setText(owner_name);
+                }
+            }
+            else
+            {
+                mParcelOwner->setText(getString("public"));
+            }
+
 			// Moved landmark creation here from LLPanelLandmarkInfo::processParcelInfo()
 			// because we use only agent's current coordinates instead of waiting for
 			// remote parcel request to complete.
@@ -210,6 +229,24 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
 	}
 
+    if (parcel_data.owner_id.notNull())
+    {
+        if (parcel_data.flags & 0x4) // depends onto DRTSIM-453
+        {
+            std::string owner_name = LLSLURL("group", parcel_data.owner_id, "inspect").getSLURLString();
+            mParcelOwner->setText(owner_name);
+        }
+        else
+        {
+            std::string owner_name = LLSLURL("agent", parcel_data.owner_id, "inspect").getSLURLString();
+            mParcelOwner->setText(owner_name);
+        }
+    }
+    else
+    {
+        mParcelOwner->setText(getString("public"));
+    }
+
 	LLSD info;
 	info["update_verbs"] = true;
 	info["global_x"] = parcel_data.global_x;
@@ -264,7 +301,8 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)
 	}
 	else
 	{
-		mOwner->setText(getString("public"));
+		std::string public_str = getString("public");
+		mOwner->setText(public_str);
 	}
 
 	//////////////////
@@ -311,6 +349,7 @@ void LLPanelLandmarkInfo::toggleLandmarkEditMode(BOOL enabled)
 		mNotesEditor->setReadOnly(!enabled);
 		mFolderCombo->setVisible(enabled);
 		getChild<LLTextBox>("folder_label")->setVisible(enabled);
+		getChild<LLButton>("edit_btn")->setVisible(!enabled);
 
 		// HACK: To change the text color in a text editor
 		// when it was enabled/disabled we set the text once again.
@@ -357,7 +396,7 @@ void LLPanelLandmarkInfo::createLandmark(const LLUUID& folder_id)
 		// If no parcel exists use the region name instead.
 		if (name.empty())
 		{
-			name = mRegionName->getText();
+			name = mRegionTitle;
 		}
 	}
 
diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h
index 01a6fd6b3d9dd73209ec687e59bb9e36c5beba8d..9712736182bcfafe46f3ab62104295eb600f970d 100644
--- a/indra/newview/llpanellandmarkinfo.h
+++ b/indra/newview/llpanellandmarkinfo.h
@@ -71,7 +71,7 @@ class LLPanelLandmarkInfo : public LLPanelPlaceInfo
 	LLTextBox*			mOwner;
 	LLTextBox*			mCreator;
 	LLTextBox*			mCreated;
-	LLTextBox*			mLandmarkTitle;
+	LLLineEditor*		mLandmarkTitle;
 	LLLineEditor*		mLandmarkTitleEditor;
 	LLTextEditor*		mNotesEditor;
 	LLComboBox*			mFolderCombo;
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index cd1dc0f0701de1e5173fe84d353a9449060df4c8..ccd8497484523075366756322e9706c763e1b5b6 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -227,6 +227,12 @@ BOOL LLLandmarksPanel::postBuild()
 	initMyInventoryPanel();
 	initLibraryInventoryPanel();
 
+	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
+	if (accordion)
+	{
+		accordion->setSkipScrollToChild(true);
+	}
+
 	return TRUE;
 }
 
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index da21d5e69a694c9ea3f74caa4c300fb95dd8f1ec..a19182b01e84b02f719c5faf5e5d41936bf03675 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -563,7 +563,7 @@ void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remem
     {
         sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
         LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
-        remember_password->setValue(remember_psswrd);
+        remember_password->setValue(remember_user && remember_psswrd);
         remember_password->setEnabled(remember_user);
         sInstance->populateUserList(credential);
     }
@@ -687,7 +687,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
 		
 		if (LLPanelLogin::sInstance->mPasswordModified)
 		{
-			authenticator = LLSD::emptyMap();
 			// password is plaintext
 			authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
 			authenticator["secret"] = password;
@@ -698,6 +697,15 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
             if (credential.notNull())
             {
                 authenticator = credential->getAuthenticator();
+                if (authenticator.emptyMap())
+                {
+                    // Likely caused by user trying to log in to non-system grid
+                    // with unsupported name format, just retry
+                    LL_WARNS() << "Authenticator failed to load for: " << username << LL_ENDL;
+                    // password is plaintext
+                    authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
+                    authenticator["secret"] = password;
+                }
             }
         }
 	}
@@ -1137,7 +1145,11 @@ void LLPanelLogin::onRememberUserCheck(void*)
             remember_name->setValue(true);
             LLNotificationsUtil::add("LoginCantRemoveUsername");
         }
-        remember_psswrd->setEnabled(remember);
+        if (!remember)
+        {
+            remember_psswrd->setValue(false);
+        }
+        remember_psswrd->setEnabled(remember);        
     }
 }
 
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 0c70aa87c2bc6bf63ebd69e21fd4e442d46daaa0..9157df789fc25d4726da7a4cf7b92ae3ba056cab 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -43,6 +43,7 @@
 #include "llagent.h"
 #include "llexpandabletextbox.h"
 #include "llpanelpick.h"
+#include "llslurl.h"
 #include "lltexturectrl.h"
 #include "llviewerregion.h"
 #include "llhttpconstants.h"
@@ -78,6 +79,7 @@ BOOL LLPanelPlaceInfo::postBuild()
 	mSnapshotCtrl = getChild<LLTextureCtrl>("logo");
 	mRegionName = getChild<LLTextBox>("region_title");
 	mParcelName = getChild<LLTextBox>("parcel_title");
+	mParcelOwner = getChild<LLTextBox>("parcel_owner");
 	mDescEditor = getChild<LLExpandableTextBox>("description");
 
 	mMaturityRatingIcon = getChild<LLIconCtrl>("maturity_icon");
@@ -98,11 +100,13 @@ void LLPanelPlaceInfo::resetLocation()
 	mParcelID.setNull();
 	mRequestedID.setNull();
 	mPosRegion.clearVec();
+	mRegionTitle.clear();
 
 	std::string loading = LLTrans::getString("LoadingData");
 	mMaturityRatingText->setValue(loading);
-	mRegionName->setText(loading);
+	mRegionName->setTextArg("[REGIONAMEPOS]", loading);
 	mParcelName->setText(loading);
+	mParcelOwner->setText(loading);
 	mDescEditor->setText(loading);
 	mMaturityRatingIcon->setValue(LLUUID::null);
 
@@ -182,9 +186,11 @@ void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
 
 	std::string not_available = getString("not_available");
 	mMaturityRatingText->setValue(not_available);
-	mRegionName->setText(not_available);
+	mRegionName->setTextArg("[REGIONAMEPOS]", not_available);
 	mParcelName->setText(not_available);
+	mParcelOwner->setText(not_available);
 	mMaturityRatingIcon->setValue(LLUUID::null);
+	mRegionTitle.clear();
 
 	// Enable "Back" button that was disabled when parcel request was sent.
 	getChild<LLButton>("back_btn")->setEnabled(TRUE);
@@ -198,12 +204,34 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mSnapshotCtrl->setImageAssetID(parcel_data.snapshot_id);
 	}
 
-	if(!parcel_data.sim_name.empty())
-	{
-		mRegionName->setText(parcel_data.sim_name);
+    S32 region_x;
+    S32 region_y;
+    S32 region_z;
+
+    // If the region position is zero, grab position from the global
+    if (mPosRegion.isExactlyZero())
+    {
+        region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
+        region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
+        region_z = ll_round(parcel_data.global_z);
+    }
+    else
+    {
+        region_x = ll_round(mPosRegion.mV[VX]);
+        region_y = ll_round(mPosRegion.mV[VY]);
+        region_z = ll_round(mPosRegion.mV[VZ]);
+    }
+
+    if (!parcel_data.sim_name.empty())
+    {
+        mRegionTitle = parcel_data.sim_name;
+        std::string name_and_pos = llformat("%s (%d, %d, %d)",
+                                   mRegionTitle.c_str(), region_x, region_y, region_z);
+        mRegionName->setTextArg("[REGIONAMEPOS]", name_and_pos);
 	}
 	else
 	{
+		mRegionTitle.clear();
 		mRegionName->setText(LLStringUtil::null);
 	}
 
@@ -216,30 +244,11 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mDescEditor->setText(getString("not_available"));
 	}
 
-	S32 region_x;
-	S32 region_y;
-	S32 region_z;
-
-	// If the region position is zero, grab position from the global
-	if(mPosRegion.isExactlyZero())
-	{
-		region_x = ll_round(parcel_data.global_x) % REGION_WIDTH_UNITS;
-		region_y = ll_round(parcel_data.global_y) % REGION_WIDTH_UNITS;
-		region_z = ll_round(parcel_data.global_z);
-	}
-	else
-	{
-		region_x = ll_round(mPosRegion.mV[VX]);
-		region_y = ll_round(mPosRegion.mV[VY]);
-		region_z = ll_round(mPosRegion.mV[VZ]);
-	}
-
 	if (!parcel_data.name.empty())
 	{
 		mParcelTitle = parcel_data.name;
 
-		mParcelName->setText(llformat("%s (%d, %d, %d)",
-							 mParcelTitle.c_str(), region_x, region_y, region_z));
+		mParcelName->setText(mParcelTitle);
 	}
 	else
 	{
@@ -280,12 +289,10 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
 
 void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
 {
-	std::string region_name = mRegionName->getText();
-
 	LLPickData data;
 	data.pos_global = pos_global;
-	data.name = mParcelTitle.empty() ? region_name : mParcelTitle;
-	data.sim_name = region_name;
+	data.name = mParcelTitle.empty() ? mRegionTitle : mParcelTitle;
+	data.sim_name = mRegionTitle;
 	data.desc = mDescEditor->getText();
 	data.snapshot_id = mSnapshotCtrl->getImageAssetID();
 	data.parcel_id = mParcelID;
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 30327378eff8c09a9d382e83ff3f7ca0881878e3..8bf67cfe7d41fdd23dcdacbbe443265bfc3de627 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -109,6 +109,7 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	LLUUID					mRequestedID;
 	LLVector3				mPosRegion;
 	std::string				mParcelTitle; // used for pick title without coordinates
+	std::string				mRegionTitle;
 	std::string				mCurrentTitle;
 	S32						mScrollingPanelMinHeight;
 	S32						mScrollingPanelWidth;
@@ -120,6 +121,7 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	LLTextureCtrl*			mSnapshotCtrl;
 	LLTextBox*				mRegionName;
 	LLTextBox*				mParcelName;
+	LLTextBox*				mParcelOwner;
 	LLExpandableTextBox*	mDescEditor;
 	LLIconCtrl*				mMaturityRatingIcon;
 	LLTextBox*				mMaturityRatingText;
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 104316e2534bcf5d08e67534843f5bfaa1a800b4..9283dfa218c57af60ce7095922b26f2a686ef43f 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -104,8 +104,6 @@ BOOL LLPanelPlaceProfile::postBuild()
 	mForSalePanel->getChild<LLIconCtrl>("icon_for_sale")->
 				setMouseDownCallback(boost::bind(&LLPanelPlaceProfile::onForSaleBannerClick, this));
 
-	mParcelOwner = getChild<LLTextBox>("owner_value");
-
 	mParcelRatingIcon = getChild<LLIconCtrl>("rating_icon");
 	mParcelRatingText = getChild<LLTextBox>("rating_value");
 	mVoiceIcon = getChild<LLIconCtrl>("voice_icon");
@@ -183,7 +181,6 @@ void LLPanelPlaceProfile::resetLocation()
 	mYouAreHerePanel->setVisible(FALSE);
 
 	std::string loading = LLTrans::getString("LoadingData");
-	mParcelOwner->setValue(loading);
 
 	mParcelRatingIcon->setValue(loading);
 	mParcelRatingText->setText(loading);
@@ -248,14 +245,14 @@ void LLPanelPlaceProfile::setInfoType(EInfoType type)
 		const S32 SEARCH_DESC_HEIGHT = 150;
 
 		// Remember original geometry (once).
-		static const S32 sOrigDescVPad = getChildView("parcel_title")->getRect().mBottom - mDescEditor->getRect().mTop;
+		static const S32 sOrigDescVPad = getChildView("owner_label")->getRect().mBottom - mDescEditor->getRect().mTop;
 		static const S32 sOrigDescHeight = mDescEditor->getRect().getHeight();
 		static const S32 sOrigMRIconVPad = mDescEditor->getRect().mBottom - mMaturityRatingIcon->getRect().mTop;
 		static const S32 sOrigMRTextVPad = mDescEditor->getRect().mBottom - mMaturityRatingText->getRect().mTop;
 
 		// Resize the description.
 		const S32 desc_height = is_info_type_agent ? sOrigDescHeight : SEARCH_DESC_HEIGHT;
-		const S32 desc_top = getChildView("parcel_title")->getRect().mBottom - sOrigDescVPad;
+		const S32 desc_top = getChildView("owner_label")->getRect().mBottom - sOrigDescVPad;
 		LLRect desc_rect = mDescEditor->getRect();
 		desc_rect.setOriginAndSize(desc_rect.mLeft, desc_top - desc_height, desc_rect.getWidth(), desc_height);
 		mDescEditor->reshape(desc_rect.getWidth(), desc_rect.getHeight());
@@ -401,6 +398,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 	parcel_data.global_x = pos_global.mdV[VX];
 	parcel_data.global_y = pos_global.mdV[VY];
 	parcel_data.global_z = pos_global.mdV[VZ];
+	parcel_data.owner_id = parcel->getOwnerID();
 
 	std::string on = getString("on");
 	std::string off = getString("off");
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index 3d2654fc129121cc1b5563257f83c845745243d5..16478bc1798bb7eee8f0a71fe633dd1e85e668ee 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -76,8 +76,6 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo
 	LLPanel*			mForSalePanel;
 	LLPanel*			mYouAreHerePanel;
 
-	LLTextBox*			mParcelOwner;
-
 	LLIconCtrl*			mParcelRatingIcon;
 	LLTextBox*			mParcelRatingText;
 	LLIconCtrl*			mVoiceIcon;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 2ef82d0cf907c0702a9370e51eb03498e07a1f99..53870fb5c74282ec3196a7ead7a13ab1ae234e94 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -59,6 +59,7 @@
 #include "llinventorymodel.h"
 #include "lllandmarkactions.h"
 #include "lllandmarklist.h"
+#include "lllayoutstack.h"
 #include "llpanellandmarkinfo.h"
 #include "llpanellandmarks.h"
 #include "llpanelpick.h"
@@ -280,9 +281,6 @@ BOOL LLPanelPlaces::postBuild()
 	mShowOnMapBtn = getChild<LLButton>("map_btn");
 	mShowOnMapBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShowOnMapButtonClicked, this));
 
-	mEditBtn = getChild<LLButton>("edit_btn");
-	mEditBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
-
 	mSaveBtn = getChild<LLButton>("save_btn");
 	mSaveBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onSaveButtonClicked, this));
 
@@ -355,6 +353,9 @@ BOOL LLPanelPlaces::postBuild()
 	LLComboBox* folder_combo = mLandmarkInfo->getChild<LLComboBox>("folder_combo");
 	folder_combo->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
 
+	LLButton* edit_btn = mLandmarkInfo->getChild<LLButton>("edit_btn");
+	edit_btn->setCommitCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this));
+
 	createTabs();
 	updateVerbs();
 
@@ -532,7 +533,6 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)
 	BOOL is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) &&
 								mItem->getPermissions().allowModifyBy(gAgent.getID());
 
-	mEditBtn->setEnabled(is_landmark_editable);
 	mSaveBtn->setEnabled(is_landmark_editable);
 
 	if (is_landmark_editable)
@@ -1216,13 +1216,16 @@ void LLPanelPlaces::updateVerbs()
 
 	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
 	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
-	mOverflowBtn->setVisible(is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
-	mEditBtn->setVisible(mPlaceInfoType == LANDMARK_INFO_TYPE && !isLandmarkEditModeOn);
 	mSaveBtn->setVisible(isLandmarkEditModeOn);
 	mCancelBtn->setVisible(isLandmarkEditModeOn);
 	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
 	mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
 
+	bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn;
+	mOverflowBtn->setVisible(show_options_btn);
+	getChild<LLLayoutPanel>("lp_options")->setVisible(show_options_btn);
+	getChild<LLLayoutPanel>("lp2")->setVisible(!show_options_btn);
+
 	mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
 
 	if (is_place_info_visible)
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 27f991c202a2f8cb7985ac5dc63075b3c3372498..978b030b2e02f7e169ea8b55ba42e8b1cd329b44 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -121,7 +121,6 @@ class LLPanelPlaces : public LLPanel
 	LLButton*					mPlaceProfileBackBtn;
 	LLButton*					mTeleportBtn;
 	LLButton*					mShowOnMapBtn;
-	LLButton*					mEditBtn;
 	LLButton*					mSaveBtn;
 	LLButton*					mCancelBtn;
 	LLButton*					mCloseBtn;
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 89cb495db94023bf67573e99788814c0a772f0a8..3347c4068771fa42887b805ec6521c8ca6678983 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -64,7 +64,9 @@ class LLWearingGearMenu
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 
-		registrar.add("Gear.Edit", boost::bind(&edit_outfit));
+		registrar.add("Gear.TouchAttach", boost::bind(&LLWearingGearMenu::handleMultiple, this, handle_attachment_touch));
+		registrar.add("Gear.EditItem", boost::bind(&LLWearingGearMenu::handleMultiple, this, handle_item_edit));
+		registrar.add("Gear.EditOutfit", boost::bind(&edit_outfit));
 		registrar.add("Gear.TakeOff", boost::bind(&LLPanelWearing::onRemoveItem, mPanelWearing));
 		registrar.add("Gear.Copy", boost::bind(&LLPanelWearing::copyToClipboard, mPanelWearing));
 
@@ -78,6 +80,16 @@ class LLWearingGearMenu
 	LLToggleableMenu* getMenu() { return mMenu; }
 
 private:
+	void handleMultiple(std::function<void(const LLUUID& id)> functor)
+	{
+		uuid_vec_t selected_item_ids;
+		mPanelWearing->getSelectedItemsUUIDs(selected_item_ids);
+
+		for (const LLUUID& item_id : selected_item_ids)
+		{
+			functor(item_id);
+		}
+	}
 
 	LLToggleableMenu*		mMenu;
 	LLPanelWearing* 		mPanelWearing;
@@ -92,7 +104,9 @@ class LLWearingContextMenu : public LLListContextMenu
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
-		registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
+		registrar.add("Wearing.TouchAttach", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
+		registrar.add("Wearing.EditItem", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
+		registrar.add("Wearing.EditOutfit", boost::bind(&edit_outfit));
 		registrar.add("Wearing.ShowOriginal", boost::bind(show_item_original, mUUIDs.front()));
 		registrar.add("Wearing.TakeOff",
 					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
@@ -138,14 +152,19 @@ class LLWearingContextMenu : public LLListContextMenu
 		}
 
 		// Enable/disable some menu items depending on the selection.
+		bool show_touch = !bp_selected && !clothes_selected && attachments_selected;
+		bool show_edit = bp_selected || clothes_selected || attachments_selected;
 		bool allow_detach = !bp_selected && !clothes_selected && attachments_selected;
 		bool allow_take_off = !bp_selected && clothes_selected && !attachments_selected;
 
+		menu->setItemVisible("touch_attach",       show_touch);
+		menu->setItemEnabled("touch_attach",       1 == mUUIDs.size() && enable_attachment_touch(mUUIDs.front()));
+		menu->setItemVisible("edit_item",          show_edit);
+		menu->setItemEnabled("edit_item",          1 == mUUIDs.size() && get_is_item_editable(mUUIDs.front()));
 		menu->setItemVisible("take_off",	allow_take_off);
 		menu->setItemVisible("detach",		allow_detach);
-		menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach);
+		menu->setItemVisible("edit_outfit_separator", show_touch | show_edit | allow_take_off || allow_detach);
 		menu->setItemVisible("show_original", mUUIDs.size() == 1);
-		menu->setItemVisible("edit_item", FALSE);
 	}
 };
 
@@ -173,12 +192,15 @@ class LLTempAttachmentsContextMenu : public LLListContextMenu
 
 	void updateMenuItemsVisibility(LLContextMenu* menu)
 	{
+		menu->setItemVisible("touch_attach", TRUE);
+		menu->setItemEnabled("touch_attach", 1 == mUUIDs.size());
+		menu->setItemVisible("edit_item", TRUE);
+		menu->setItemEnabled("edit_item", 1 == mUUIDs.size());
 		menu->setItemVisible("take_off", FALSE);
 		menu->setItemVisible("detach", TRUE);
-		menu->setItemVisible("edit_outfit_separator", TRUE);
+		menu->setItemVisible("edit_outfit_separator", FALSE);
 		menu->setItemVisible("show_original", FALSE);
-		menu->setItemVisible("edit_item", TRUE);
-		menu->setItemVisible("edit", FALSE);
+		menu->setItemVisible("edit_outfit", FALSE);
 	}
 
 	LLPanelWearing* 		mPanelWearing;
@@ -350,6 +372,18 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
 		}
 	}
 
+	uuid_vec_t selected_uuids;
+	getSelectedItemsUUIDs(selected_uuids);
+
+	if (command_name == "touch_attach")
+	{
+		return (1 == selected_uuids.size()) && (enable_attachment_touch(selected_uuids.front()));
+	}
+	else if (command_name == "edit_item")
+	{
+		return (1 == selected_uuids.size()) && (get_is_item_editable(selected_uuids.front()));
+	}
+
 	return false;
 }
 
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 7ef0ef0e8b78a5bd294fd7ae942012f632f80c36..1b60610668d38734255b17cbd0f826756bb2bc7a 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -307,6 +307,7 @@ void LLPreviewNotecard::loadAsset()
 		{
 			editor->setEnabled(FALSE);
 			getChildView("lock")->setVisible( TRUE);
+			getChildView("Edit")->setEnabled(FALSE);
 		}
 
 		if((allow_modify || is_owner) && !source_library)
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 5b0d1891378fbbbb4975e6010e13c691952972ff..70c117be44e7c3084ad1dd79d22e91457396ce8c 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -45,7 +45,7 @@ struct LLParcelData
 	std::string	desc;
 	S32			actual_area;
 	S32			billable_area;
-	U8			flags;
+	U8			flags; // group owned, maturity
 	F32			global_x;
 	F32			global_y;
 	F32			global_z;
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index 93143eb33fe6589ea898cbb0f21a23db81dd95b9..1119e80005ecaee81ff95099a46f9f3d493b4063 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -68,7 +68,10 @@ ll::prefs::PanelData::~PanelData()
 bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
 {
 	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
-		(*itr)->setNotHighlighted( );
+		(*itr)->setNotHighlighted();
+
+	for (tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr)
+		(*itr)->setNotHighlighted();
 
 	if (aFilter.empty())
 	{
@@ -85,6 +88,15 @@ bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter )
 	return bVisible;
 }
 
+void ll::prefs::PanelData::setNotHighlighted()
+{
+	for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr)
+		(*itr)->setNotHighlighted();
+
+	for (tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr)
+		(*itr)->setNotHighlighted();
+}
+
 bool ll::prefs::TabContainerData::hightlightAndHide( LLWString const &aFilter )
 {
 	for( tSearchableItemList::iterator itr = mChildren.begin(); itr  != mChildren.end(); ++itr )
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index 9741557e49ea7b113ec74ce281e2803c727ec28c..e033cae3abe2597e910dbce7ad567daf6bbd6aab 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -73,6 +73,7 @@ namespace ll
 
 			virtual ~PanelData();
 
+			void setNotHighlighted();
 			virtual bool hightlightAndHide( LLWString const &aFilter );
 		};
 
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 26a2df8270365c72775cc9597026c2efe70dba75..b9259cb18dfd6833854d4edc8545613e8da24622 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -117,7 +117,7 @@ LLSD LLCredential::getLoginParams()
 		else if (mIdentifier["type"].asString() == "account")
 		{
 			result["username"] = mIdentifier["account_name"];
-			result["passwd"] = mAuthenticator["secret"];
+			result["passwd"] = mAuthenticator["secret"].asString();
 			username = result["username"].asString();
 		}
 	}
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index f3439daee9aede33fc26af4403ececcfa60965e0..8369def9688be570ea06c73e2e847cba777fd132 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -155,7 +155,7 @@ F32 LLSnapshotLivePreview::getImageAspect()
 
 void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay)
 {
-	LL_DEBUGS() << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << LL_ENDL;
+	LL_DEBUGS("Snapshot") << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << LL_ENDL;
 
 	// Update snapshot if requested.
 	if (new_snapshot)
@@ -343,7 +343,7 @@ void LLSnapshotLivePreview::draw()
 		}
 		else if (mShineAnimTimer.getStarted())
 		{
-			LL_DEBUGS() << "Drawing shining animation" << LL_ENDL;
+			LL_DEBUGS("Snapshot") << "Drawing shining animation" << LL_ENDL;
 			F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
 
 			// draw "shine" effect
@@ -391,7 +391,7 @@ void LLSnapshotLivePreview::draw()
 		S32 old_image_index = (mCurImageIndex + 1) % 2;
 		if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
 		{
-			LL_DEBUGS() << "Drawing fall animation" << LL_ENDL;
+			LL_DEBUGS("Snapshot") << "Drawing fall animation" << LL_ENDL;
 			F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
 			F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
 			LLColor4 image_color(1.f, 1.f, 1.f, alpha);
@@ -435,7 +435,7 @@ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_pare
 	LLView::reshape(width, height, called_from_parent);
 	if (old_rect.getWidth() != width || old_rect.getHeight() != height)
 	{
-		LL_DEBUGS() << "window reshaped, updating thumbnail" << LL_ENDL;
+		LL_DEBUGS("Window", "Snapshot") << "window reshaped, updating thumbnail" << LL_ENDL;
 		if (mViewContainer && mViewContainer->isInVisibleChain())
 		{
 			// We usually resize only on window reshape, so give it a chance to redraw, assign delay
@@ -580,7 +580,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
             }
             else
             {
-                LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+                LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
             }
         }
         // Scale to a power of 2 so it can be mapped to a texture
@@ -628,7 +628,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage()
             }
             else
             {
-                LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+                LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
             }
         }
         // Scale to a power of 2 so it can be mapped to a texture
@@ -648,7 +648,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
 	if (previewp->getWidth() == 0 || previewp->getHeight() == 0)
 	{
-		LL_WARNS() << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << LL_ENDL;
+		LL_WARNS("Snapshot") << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << LL_ENDL;
 		return FALSE;
 	}
 
@@ -679,7 +679,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 		previewp->mCameraRot = new_camera_rot;
 		// request a new snapshot whenever the camera moves, with a time delay
 		BOOL new_snapshot = gSavedSettings.getBOOL("AutoSnapshot") || previewp->mForceUpdateSnapshot;
-		LL_DEBUGS() << "camera moved, updating thumbnail" << LL_ENDL;
+		LL_DEBUGS("Snapshot") << "camera moved, updating thumbnail" << LL_ENDL;
 		previewp->updateSnapshot(
 			new_snapshot, // whether a new snapshot is needed or merely invalidate the existing one
 			FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
@@ -695,7 +695,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 	// time to produce a snapshot
 	if(!previewp->getSnapshotUpToDate())
     {
-        LL_DEBUGS() << "producing snapshot" << LL_ENDL;
+        LL_DEBUGS("Snapshot") << "producing snapshot" << LL_ENDL;
         if (!previewp->mPreviewImage)
         {
             previewp->mPreviewImage = new LLImageRaw;
@@ -745,7 +745,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
         previewp->getWindow()->decBusyCount();
         previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview); // only show fullscreen preview when in freeze frame mode
         previewp->mSnapshotActive = FALSE;
-        LL_DEBUGS() << "done creating snapshot" << LL_ENDL;
+        LL_DEBUGS("Snapshot") << "done creating snapshot" << LL_ENDL;
     }
     
     if (!previewp->getThumbnailUpToDate())
@@ -836,7 +836,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
         if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
 		{
             // We don't store the intermediate formatted image in mFormattedImage in the J2C case 
-			LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL;
+			LL_DEBUGS("Snapshot") << "Encoding new image of format J2C" << LL_ENDL;
 			LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
             // Copy the preview
 			LLPointer<LLImageRaw> scaled = new LLImageRaw(
@@ -921,13 +921,13 @@ LLPointer<LLImageFormatted>	LLSnapshotLivePreview::getFormattedImage()
             }
             else
             {
-                LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+                LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
             }
         }
         
         // Create the new formatted image of the appropriate format.
         LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat();
-        LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL;
+        LL_DEBUGS("Snapshot") << "Encoding new image of format " << format << LL_ENDL;
             
         switch (format)
         {
@@ -952,7 +952,7 @@ LLPointer<LLImageFormatted>	LLSnapshotLivePreview::getFormattedImage()
 
 void LLSnapshotLivePreview::setSize(S32 w, S32 h)
 {
-	LL_DEBUGS() << "setSize(" << w << ", " << h << ")" << LL_ENDL;
+    LL_DEBUGS("Snapshot") << "setSize(" << w << ", " << h << ")" << LL_ENDL;
 	setWidth(w);
 	setHeight(h);
 }
@@ -974,7 +974,7 @@ void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
 
 void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
 {
-	LL_DEBUGS() << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
+	LL_DEBUGS("Snapshot") << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
 	// gen a new uuid for this asset
 	LLTransactionID tid;
 	tid.generate();
@@ -997,12 +997,12 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
 		}
 		else
 		{
-			LL_WARNS() << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
+			LL_WARNS("Snapshot") << "Couldn't find a path to the following filter : " << getFilter() << LL_ENDL;
 		}
 	}
 
 	scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
-	LL_DEBUGS() << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << LL_ENDL;
+	LL_DEBUGS("Snapshot") << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << LL_ENDL;
 
 	if (formatted->encode(scaled, 0.0f))
 	{
@@ -1030,7 +1030,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
 	else
 	{
 		LLNotificationsUtil::add("ErrorEncodingSnapshot");
-		LL_WARNS() << "Error encoding snapshot" << LL_ENDL;
+		LL_WARNS("Snapshot") << "Error encoding snapshot" << LL_ENDL;
 	}
 
 	add(LLStatViewer::SNAPSHOT, 1);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index afb25778aa257db495b7f5c0e9b104b52cfab674..8fc2405f0a683af59efb6ab539aa601a9a3fdc6e 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3125,13 +3125,13 @@ void renderRaycast(LLDrawable* drawablep)
 		LLGLEnable blend(GL_BLEND);
 		gGL.diffuseColor4f(0,1,1,0.5f);
 
-		if (drawablep->getVOVolume())
+		LLVOVolume* vobj = drawablep->getVOVolume();
+		if (vobj && !vobj->isDead())
 		{
 			//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 			//pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
 			//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
-			LLVOVolume* vobj = drawablep->getVOVolume();
 			LLVolume* volume = vobj->getVolume();
 
 			bool transform = true;
@@ -3360,7 +3360,7 @@ class LLOctreeRenderNonOccluded : public OctreeTraveler
 		for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
 		{
 			LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
-			if(!drawable)
+			if(!drawable || drawable->isDead())
 		{
 				continue;
 			}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ad794b035ed8f7537b1f7c06e9de652504faeb0b..796a3a019378decdcca14392bfaf1193003f11fb 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1230,7 +1230,6 @@ bool idle_startup()
 		display_startup();
 		gAgentCamera.init();
 		display_startup();
-		set_underclothes_menu_options();
 		display_startup();
 
 		// Since we connected, save off the settings so the user doesn't have to
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index c65431d6f62a5dc1bd0d9feed75ea0ea30959ea5..8aa5b0756159ed02c03ba6e79335cb1bab93a37d 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -187,6 +187,16 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
 
 bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
 {
+	LLRenderTarget::sUseFBO = newvalue.asBoolean();
+	if (gPipeline.isInit())
+	{
+		gPipeline.updateRenderTransparentWater();
+		gPipeline.updateRenderDeferred();
+		gPipeline.releaseGLBuffers();
+		gPipeline.createGLBuffers();
+		gPipeline.resetVertexBuffers();
+		LLViewerShaderMgr::instance()->setShaders();
+	}
 	LLWorld::getInstance()->updateWaterObjects();
 	return true;
 }
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index caf79edfe4ac12c73b93617344806c2358d4c300..d314b1477aa4f3ff1a9c3944b2f1f475980aeb71 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -423,6 +423,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
 		{
 			// Give up.  Don't keep the UI locked forever.
+			LL_WARNS("Teleport") << "Giving up on teleport. elapsed time " << teleport_elapsed << " exceeds max time " << teleport_save_time << LL_ENDL;
 			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 			gAgent.setTeleportMessage(std::string());
 		}
@@ -444,6 +445,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gTeleportDisplayTimer.reset();
 			gViewerWindow->setShowProgress(TRUE);
 			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+			LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
 			gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
 			gAgent.setTeleportMessage(
 				LLAgent::sTeleportProgressMessages["requesting"]);
@@ -468,6 +470,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gTeleportArrivalTimer.reset();
 				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
 			gViewerWindow->setProgressPercent(75.f);
+			LL_INFOS("Teleport") << "Changing state to TELEPORT_ARRIVING" << LL_ENDL;
 			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
 			gAgent.setTeleportMessage(
 				LLAgent::sTeleportProgressMessages["arriving"]);
@@ -484,6 +487,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				{
 					arrival_fraction = 1.f;
 					//LLFirstUse::useTeleport();
+					LL_INFOS("Teleport") << "arrival_fraction is " << arrival_fraction << " changing state to TELEPORT_NONE" << LL_ENDL;
 					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 				}
 				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
@@ -499,6 +503,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				if( gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay() )
 				{
 					//LLFirstUse::useTeleport();
+					LL_INFOS("Teleport") << "State is local and gTeleportDisplayTimer " << gTeleportDisplayTimer.getElapsedTimeF32()
+										 << " exceeds teleport_local_delete " << teleport_local_delay
+										 << "; setting state to TELEPORT_NONE"
+										 << LL_ENDL;
 					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 				}
 			}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d0cbd1181bf39d25252cf84aa6d10c390d4ff897..bbed741a33c0e422094df39fabd1d21f6a71717a 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -81,6 +81,9 @@ static const char * const LOG_INV("Inventory");
 static const char * const LOG_LOCAL("InventoryLocalize");
 static const char * const LOG_NOTECARD("copy_inventory_from_notecard");
 
+static const std::string INV_OWNER_ID("owner_id");
+static const std::string INV_VERSION("version");
+
 #if 1
 // *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model.
 // temp code in transition
@@ -518,14 +521,6 @@ void LLViewerInventoryItem::packMessage(LLMessageSystem* msg) const
 	msg->addU32Fast(_PREHASH_CRC, crc);
 }
 
-// virtual
-BOOL LLViewerInventoryItem::importFile(LLFILE* fp)
-{
-	BOOL rv = LLInventoryItem::importFile(fp);
-	mIsComplete = TRUE;
-	return rv;
-}
-
 // virtual
 BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
 {
@@ -534,32 +529,6 @@ BOOL LLViewerInventoryItem::importLegacyStream(std::istream& input_stream)
 	return rv;
 }
 
-bool LLViewerInventoryItem::importFileLocal(LLFILE* fp)
-{
-	// TODO: convert all functions that return BOOL to return bool
-	bool rv = (LLInventoryItem::importFile(fp) ? true : false);
-	mIsComplete = false;
-	return rv;
-}
-
-bool LLViewerInventoryItem::exportFileLocal(LLFILE* fp) const
-{
-	std::string uuid_str;
-	fprintf(fp, "\tinv_item\t0\n\t{\n");
-	mUUID.toString(uuid_str);
-	fprintf(fp, "\t\titem_id\t%s\n", uuid_str.c_str());
-	mParentUUID.toString(uuid_str);
-	fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
-	mPermissions.exportFile(fp);
-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
-	if(!inv_type_str.empty()) fprintf(fp, "\t\tinv_type\t%s\n", inv_type_str.c_str());
-	fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
-	fprintf(fp, "\t\tcreation_date\t%d\n", (S32) mCreationDate);
-	fprintf(fp,"\t}\n");
-	return true;
-}
-
 void LLViewerInventoryItem::updateParentOnServer(BOOL restamp) const
 {
 	LLMessageSystem* msg = gMessageSystem;
@@ -720,90 +689,26 @@ S32 LLViewerInventoryCategory::getViewerDescendentCount() const
 	return descendents_actual;
 }
 
-bool LLViewerInventoryCategory::importFileLocal(LLFILE* fp)
+LLSD LLViewerInventoryCategory::exportLLSD() const
 {
-	// *NOTE: This buffer size is hard coded into scanf() below.
-	char buffer[MAX_STRING];		/* Flawfinder: ignore */
-	char keyword[MAX_STRING];		/* Flawfinder: ignore */
-	char valuestr[MAX_STRING];		/* Flawfinder: ignore */
+	LLSD cat_data = LLInventoryCategory::exportLLSD();
+	cat_data[INV_OWNER_ID] = mOwnerID;
+	cat_data[INV_VERSION] = mVersion;
 
-	keyword[0] = '\0';
-	valuestr[0] = '\0';
-	while(!feof(fp))
-	{
-		if (fgets(buffer, MAX_STRING, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-		
-		sscanf(	/* Flawfinder: ignore */
-			buffer, " %254s %254s", keyword, valuestr); 
-		if(0 == strcmp("{",keyword))
-		{
-			continue;
-		}
-		if(0 == strcmp("}", keyword))
-		{
-			break;
-		}
-		else if(0 == strcmp("cat_id", keyword))
-		{
-			mUUID.set(valuestr);
-		}
-		else if(0 == strcmp("parent_id", keyword))
-		{
-			mParentUUID.set(valuestr);
-		}
-		else if(0 == strcmp("type", keyword))
-		{
-			mType = LLAssetType::lookup(valuestr);
-		}
-		else if(0 == strcmp("pref_type", keyword))
-		{
-			mPreferredType = LLFolderType::lookup(valuestr);
-		}
-		else if(0 == strcmp("name", keyword))
-		{
-			//strcpy(valuestr, buffer + strlen(keyword) + 3);
-			// *NOTE: Not ANSI C, but widely supported.
-			sscanf(	/* Flawfinder: ignore */
-				buffer, " %254s %254[^|]", keyword, valuestr);
-			mName.assign(valuestr);
-			LLStringUtil::replaceNonstandardASCII(mName, ' ');
-			LLStringUtil::replaceChar(mName, '|', ' ');
-		}
-		else if(0 == strcmp("owner_id", keyword))
-		{
-			mOwnerID.set(valuestr);
-		}
-		else if(0 == strcmp("version", keyword))
-		{
-			sscanf(valuestr, "%d", &mVersion);
-		}
-		else
-		{
-			LL_WARNS(LOG_INV) << "unknown keyword '" << keyword
-							  << "' in inventory import category "  << mUUID << LL_ENDL;
-		}
-	}
-	return true;
+	return cat_data;
 }
 
-bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const
-{
-	std::string uuid_str;
-	fprintf(fp, "\tinv_category\t0\n\t{\n");
-	mUUID.toString(uuid_str);
-	fprintf(fp, "\t\tcat_id\t%s\n", uuid_str.c_str());
-	mParentUUID.toString(uuid_str);
-	fprintf(fp, "\t\tparent_id\t%s\n", uuid_str.c_str());
-	fprintf(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	fprintf(fp, "\t\tpref_type\t%s\n", LLFolderType::lookup(mPreferredType).c_str());
-	fprintf(fp, "\t\tname\t%s|\n", mName.c_str());
-	mOwnerID.toString(uuid_str);
-	fprintf(fp, "\t\towner_id\t%s\n", uuid_str.c_str());
-	fprintf(fp, "\t\tversion\t%d\n", mVersion);
-	fprintf(fp,"\t}\n");
+bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data)
+{
+	LLInventoryCategory::importLLSD(cat_data);
+	if (cat_data.has(INV_OWNER_ID))
+	{
+		mOwnerID = cat_data[INV_OWNER_ID].asUUID();
+	}
+	if (cat_data.has(INV_VERSION))
+	{
+		setVersion(cat_data[INV_VERSION].asInteger());
+	}
 	return true;
 }
 
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index d537b2868200728b3cf0d04742cd7cbb280d520b..24b632632b911a0d734ce942ec72510906fe7b0f 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -131,14 +131,8 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	virtual void packMessage(LLMessageSystem* msg) const;
 	virtual BOOL unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
 	virtual BOOL unpackMessage(const LLSD& item);
-	virtual BOOL importFile(LLFILE* fp);
 	virtual BOOL importLegacyStream(std::istream& input_stream);
 
-	// file handling on the viewer. These are not meant for anything
-	// other than cacheing.
-	bool exportFileLocal(LLFILE* fp) const;
-	bool importFileLocal(LLFILE* fp);
-
 	// new methods
 	BOOL isFinished() const { return mIsComplete; }
 	void setComplete(BOOL complete) { mIsComplete = complete; }
@@ -226,10 +220,9 @@ class LLViewerInventoryCategory  : public LLInventoryCategory
 	// How many descendents do we currently have information for in the InventoryModel?
 	S32 getViewerDescendentCount() const;
 
-	// file handling on the viewer. These are not meant for anything
-	// other than caching.
-	bool exportFileLocal(LLFILE* fp) const;
-	bool importFileLocal(LLFILE* fp);
+	LLSD exportLLSD() const;
+	bool importLLSD(const LLSD& cat_data);
+
 	void determineFolderType();
 	void changeType(LLFolderType::EType new_folder_type);
 	virtual void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 7cb1d496a419b200506e548d0ba16cf05e9f232a..1374ec3bde0c8ff1986c87beada689f3bfd071c6 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1719,23 +1719,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		std::string user_data_path_cache = gDirUtilp->getCacheDir(false);
 		user_data_path_cache += gDirUtilp->getDirDelimiter();
 
-		std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
-		user_data_path_cookies += gDirUtilp->getDirDelimiter();
-
 		std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
 
-		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
-		// If the linden username returned is blank, that can only mean we are
-		// at the login page displaying login Web page or Web browser test via Develop menu.
-		// In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this
-		// is what we always used before this change)
-		std::string linden_user_dir = gDirUtilp->getLindenUserDir();
-		if ( ! linden_user_dir.empty() )
-		{
-			user_data_path_cookies = linden_user_dir;
-			user_data_path_cookies += gDirUtilp->getDirDelimiter();
-		};
-
 		// See if the plugin executable exists
 		llstat s;
 		if(LLFile::stat(launcher_name, &s))
@@ -1752,7 +1737,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		{
 			media_source = new LLPluginClassMedia(owner);
 			media_source->setSize(default_width, default_height);
-			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);
+			media_source->setUserDataPath(user_data_path_cache, gDirUtilp->getUserName(), user_data_path_cef_log);
 			media_source->setLanguageCode(LLUI::getLanguage());
 			media_source->setZoomFactor(zoom_factor);
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 51f641da96350fbe0184f68b745eed0320de6d55..e589ee09b112d71e73ba4b39e345cdef05a93dfc 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -375,20 +375,6 @@ void initialize_menus();
 // Break up groups of more than 6 items with separators
 //-----------------------------------------------------------------------------
 
-void set_underclothes_menu_options()
-{
-	if (gMenuHolder && gAgent.isTeen())
-	{
-		gMenuHolder->getChild<LLView>("Self Underpants")->setVisible(FALSE);
-		gMenuHolder->getChild<LLView>("Self Undershirt")->setVisible(FALSE);
-	}
-	if (gMenuBarView && gAgent.isTeen())
-	{
-		gMenuBarView->getChild<LLView>("Menu Underpants")->setVisible(FALSE);
-		gMenuBarView->getChild<LLView>("Menu Undershirt")->setVisible(FALSE);
-	}
-}
-
 void set_merchant_SLM_menu()
 {
     // All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool
@@ -2781,7 +2767,6 @@ class LLObjectBuild : public view_listener_t
 	}
 };
 
-
 void handle_object_edit()
 {
 	LLViewerParcelMgr::getInstance()->deselectLand();
@@ -2826,6 +2811,57 @@ void handle_object_edit()
 	return;
 }
 
+void handle_attachment_edit(const LLUUID& inv_item_id)
+{
+	if (isAgentAvatarValid())
+	{
+		if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id))
+		{
+			LLSelectMgr::getInstance()->deselectAll();
+			LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj);
+
+			handle_object_edit();
+		}
+	}
+}
+
+void handle_attachment_touch(const LLUUID& inv_item_id)
+{
+	if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) )
+	{
+		if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)))
+		{
+			LLSelectMgr::getInstance()->deselectAll();
+
+			LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj);
+			if (!LLToolMgr::getInstance()->inBuildMode())
+			{
+				struct SetTransient : public LLSelectedNodeFunctor
+				{
+					bool apply(LLSelectNode* node)
+					{
+						node->setTransient(TRUE);
+						return true;
+					}
+				} f;
+				sel->applyToNodes(&f);
+			}
+
+			handle_object_touch();
+		}
+	}
+}
+
+bool enable_attachment_touch(const LLUUID& inv_item_id)
+{
+	if (isAgentAvatarValid())
+	{
+		const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id));
+		return (attach_obj) && (attach_obj->flagHandleTouch());
+	}
+	return false;
+}
+
 void handle_object_inspect()
 {
 	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 68824054073894068e961be95a6709f11afc11d0..0f63c8cf58379ec8716d1a88162376201d8287f9 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -82,7 +82,6 @@ void handle_detach(void*);
 BOOL enable_god_full(void* user_data);
 BOOL enable_god_liaison(void* user_data);
 BOOL enable_god_basic(void* user_data);
-void set_underclothes_menu_options();
 void check_merchant_status(bool force = false);
 
 void exchange_callingcard(const LLUUID& dest_id);
@@ -110,6 +109,10 @@ void handle_object_return();
 void handle_object_delete();
 void handle_object_edit();
 
+void handle_attachment_edit(const LLUUID& inv_item_id);
+void handle_attachment_touch(const LLUUID& inv_item_id);
+bool enable_attachment_touch(const LLUUID& inv_item_id);
+
 void handle_buy_land();
 
 // Takes avatar UUID, or if no UUID passed, uses last selected object
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ea9dba3c4eb23ed46139ddc6c6f4a1d62be6bdb5..34d5dd5663141fdacac1c0bd19f6bfcf0841f42d 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -406,6 +406,7 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_
 
 void send_complete_agent_movement(const LLHost& sim_host)
 {
+	LL_DEBUGS("Teleport", "Messaging") << "Sending CompleteAgentMovement to sim_host " << sim_host << LL_ENDL;
 	LLMessageSystem* msg = gMessageSystem;
 	msg->newMessageFast(_PREHASH_CompleteAgentMovement);
 	msg->nextBlockFast(_PREHASH_AgentData);
@@ -2877,12 +2878,12 @@ BOOL LLPostTeleportNotifiers::tick()
 // We're going to pretend to be a new agent
 void process_teleport_finish(LLMessageSystem* msg, void**)
 {
-	LL_DEBUGS("Messaging") << "Got teleport location message" << LL_ENDL;
+	LL_DEBUGS("Teleport","Messaging") << "Received TeleportFinish message" << LL_ENDL;
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
 	if (agent_id != gAgent.getID())
 	{
-		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
+		LL_WARNS("Teleport","Messaging") << "Got teleport notification for wrong agent " << agent_id << " expected " << gAgent.getID() << ", ignoring!" << LL_ENDL;
 		return;
 	}
 
@@ -2892,12 +2893,13 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
         {
             // Server either ignored teleport cancel message or did not receive it in time.
             // This message can't be ignored since teleport is complete at server side
+			LL_INFOS("Teleport") << "Restoring canceled teleport request" << LL_ENDL;
             gAgent.restoreCanceledTeleportRequest();
         }
         else
         {
             // Race condition? Make sure all variables are set correctly for teleport to work
-            LL_WARNS("Messaging") << "Teleport 'finish' message without 'start'" << LL_ENDL;
+            LL_WARNS("Teleport","Messaging") << "Teleport 'finish' message without 'start'. Setting state to TELEPORT_REQUESTED" << LL_ENDL;
             gTeleportDisplay = TRUE;
             LLViewerMessage::getInstance()->mTeleportStartedSignal();
             gAgent.setTeleportState(LLAgent::TELEPORT_REQUESTED);
@@ -2906,7 +2908,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
     }
     else if (gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING)
     {
-        LL_WARNS("Messaging") << "Teleport message in the middle of other teleport" << LL_ENDL;
+        LL_WARNS("Teleport","Messaging") << "Teleport message in the middle of other teleport" << LL_ENDL;
     }
 	
 	// Teleport is finished; it can't be cancelled now.
@@ -2934,11 +2936,18 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 	msg->getU64Fast(_PREHASH_Info, _PREHASH_RegionHandle, region_handle);
 	U32 teleport_flags;
 	msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
-	
-	
+
 	std::string seedCap;
 	msg->getStringFast(_PREHASH_Info, _PREHASH_SeedCapability, seedCap);
 
+	LL_DEBUGS("Teleport") << "TeleportFinish message params are:"
+						  << " sim_ip " << sim_ip
+						  << " sim_port " << sim_port
+						  << " region_handle " << region_handle
+						  << " teleport_flags " << teleport_flags
+						  << " seedCap " << seedCap
+						  << LL_ENDL;
+	
 	// update home location if we are teleporting out of prelude - specific to teleporting to welcome area 
 	if((teleport_flags & TELEPORT_FLAGS_SET_HOME_TO_TARGET)
 	   && (!gAgent.isGodlike()))
@@ -2980,7 +2989,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 	gAgent.standUp();
 
 	// now, use the circuit info to tell simulator about us!
-	LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
+	LL_INFOS("Teleport","Messaging") << "process_teleport_finish() sending UseCircuitCode to enable sim_host "
 			<< sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;
 	msg->newMessageFast(_PREHASH_UseCircuitCode);
 	msg->nextBlockFast(_PREHASH_CircuitCode);
@@ -2989,11 +2998,12 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 	msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
 	msg->sendReliable(sim_host);
 
+	LL_INFOS("Teleport") << "Calling send_complete_agent_movement() and setting state to TELEPORT_MOVING" << LL_ENDL;
 	send_complete_agent_movement(sim_host);
 	gAgent.setTeleportState( LLAgent::TELEPORT_MOVING );
 	gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["contacting"]);
 
-	LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from process_teleport_finish(). Seed cap == "
+	LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability(). Seed cap == "
 			<< seedCap << LL_ENDL;
 	regionp->setSeedCapability(seedCap);
 
@@ -3026,6 +3036,8 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
 
 void process_agent_movement_complete(LLMessageSystem* msg, void**)
 {
+	LL_INFOS("Teleport","Messaging") << "Received ProcessAgentMovementComplete" << LL_ENDL;
+
 	gShiftFrame = true;
 	gAgentMovementCompleted = true;
 
@@ -3035,13 +3047,13 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
 	if((gAgent.getID() != agent_id) || (gAgent.getSessionID() != session_id))
 	{
-		LL_WARNS("Messaging") << "Incorrect id in process_agent_movement_complete()"
-				<< LL_ENDL;
+		LL_WARNS("Teleport", "Messaging") << "Incorrect agent or session id in process_agent_movement_complete()"
+										  << " agent " << agent_id << " expected " << gAgent.getID() 
+										  << " session " << session_id << " expected " << gAgent.getSessionID()
+										  << ", ignoring" << LL_ENDL;
 		return;
 	}
 
-	LL_DEBUGS("Messaging") << "process_agent_movement_complete()" << LL_ENDL;
-
 	// *TODO: check timestamp to make sure the movement compleation
 	// makes sense.
 	LLVector3 agent_pos;
@@ -3058,7 +3070,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 	{
 		// Could happen if you were immediately god-teleported away on login,
 		// maybe other cases.  Continue, but warn.
-		LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
+		LL_WARNS("Teleport", "Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
 	}
 
 	F32 x, y;
@@ -3068,19 +3080,21 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 	{
 		if (gAgent.getRegion())
 		{
-			LL_WARNS("Messaging") << "current region " << gAgent.getRegion()->getOriginGlobal() << LL_ENDL;
+			LL_WARNS("Teleport", "Messaging") << "current region origin "
+											  << gAgent.getRegion()->getOriginGlobal() << " id " << gAgent.getRegion()->getRegionID() << LL_ENDL;
 		}
 
-		LL_WARNS("Messaging") << "Agent being sent to invalid home region: " 
-			<< x << ":" << y 
-			<< " current pos " << gAgent.getPositionGlobal()
-			<< LL_ENDL;
+		LL_WARNS("Teleport", "Messaging") << "Agent being sent to invalid home region: " 
+										  << x << ":" << y 
+										  << " current pos " << gAgent.getPositionGlobal()
+										  << ", calling forceDisconnect()"
+										  << LL_ENDL;
 		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("SentToInvalidRegion"));
 		return;
 
 	}
 
-	LL_INFOS("Messaging") << "Changing home region to " << x << ":" << y << LL_ENDL;
+	LL_INFOS("Teleport","Messaging") << "Changing home region to region id " << regionp->getRegionID() << " handle " << region_handle << " == x,y " << x << "," << y << LL_ENDL;
 
 	// set our upstream host the new simulator and shuffle things as
 	// appropriate.
@@ -3108,6 +3122,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 		gAgentCamera.slamLookAt(look_at);
 		gAgentCamera.updateCamera();
 
+		LL_INFOS("Teleport") << "Agent movement complete, setting state to TELEPORT_START_ARRIVAL" << LL_ENDL;
 		gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
 
 		if (isAgentAvatarValid())
@@ -3121,6 +3136,8 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 	else
 	{
 		// This is initial log-in or a region crossing
+		LL_INFOS("Teleport") << "State is not TELEPORT_MOVING, so this is initial log-in or region crossing. "
+							 << "Setting state to TELEPORT_NONE" << LL_ENDL;
 		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 
 		if(LLStartUp::getStartupState() < STATE_STARTED)
@@ -5955,6 +5972,8 @@ std::string formatted_time(const time_t& the_time)
 
 void process_teleport_failed(LLMessageSystem *msg, void**)
 {
+	LL_WARNS("Teleport","Messaging") << "Received TeleportFailed message" << LL_ENDL;
+
 	std::string message_id;		// Tag from server, like "RegionEntryAccessBlocked"
 	std::string big_reason;		// Actual message to display
 	LLSD args;
@@ -5973,6 +5992,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 			// Nothing found in the map - use what the server returned in the original message block
 			msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, big_reason);
 		}
+		LL_WARNS("Teleport") << "AlertInfo message_id " << message_id << " reason: " << big_reason << LL_ENDL;
 
 		LLSD llsd_block;
 		std::string llsd_raw;
@@ -5982,10 +6002,11 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 			std::istringstream llsd_data(llsd_raw);
 			if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
 			{
-				LL_WARNS() << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << LL_ENDL;
+				LL_WARNS("Teleport") << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << LL_ENDL;
 			}
 			else
 			{
+				LL_WARNS("Teleport") << "AlertInfo llsd block received: " << llsd_block << LL_ENDL;
 				if(llsd_block.has("REGION_NAME"))
 				{
 					std::string region_name = llsd_block["REGION_NAME"].asString();
@@ -6001,6 +6022,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 				{
 					if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 					{
+						LL_WARNS("Teleport") << "called handle_teleport_access_blocked, setting state to TELEPORT_NONE" << LL_ENDL;
 						gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 					}
 					return;
@@ -6023,22 +6045,27 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 			args["REASON"] = message_id;
 		}
 	}
+	LL_WARNS("Teleport") << "Displaying CouldNotTeleportReason string, REASON= " << args["REASON"] << LL_ENDL;
 
 	LLNotificationsUtil::add("CouldNotTeleportReason", args);
 
 	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 	{
+		LL_WARNS("Teleport") << "End of process_teleport_failed(). Reason message arg is " << args["REASON"]
+							 << ". Setting state to TELEPORT_NONE" << LL_ENDL;
 		gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 	}
 }
 
 void process_teleport_local(LLMessageSystem *msg,void**)
 {
+	LL_INFOS("Teleport","Messaging") << "Received TeleportLocal message" << LL_ENDL;
+	
 	LLUUID agent_id;
 	msg->getUUIDFast(_PREHASH_Info, _PREHASH_AgentID, agent_id);
 	if (agent_id != gAgent.getID())
 	{
-		LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL;
+		LL_WARNS("Teleport", "Messaging") << "Got teleport notification for wrong agent " << agent_id << " expected " << gAgent.getID() << ", ignoring!" << LL_ENDL;
 		return;
 	}
 
@@ -6050,6 +6077,7 @@ void process_teleport_local(LLMessageSystem *msg,void**)
 	msg->getVector3Fast(_PREHASH_Info, _PREHASH_LookAt, look_at);
 	msg->getU32Fast(_PREHASH_Info, _PREHASH_TeleportFlags, teleport_flags);
 
+	LL_INFOS("Teleport") << "Message params are location_id " << location_id << " teleport_flags " << teleport_flags << LL_ENDL;
 	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 	{
 		if( gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL )
@@ -6062,6 +6090,8 @@ void process_teleport_local(LLMessageSystem *msg,void**)
 		}
 		else
 		{
+			LL_WARNS("Teleport") << "State is not TELEPORT_LOCAL: " << gAgent.getTeleportStateName()
+								 << ", setting state to TELEPORT_NONE" << LL_ENDL;
 			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
 		}
 	}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index aa775b2babb19abe34726ebe625239b3ea963006..b88baf6aa72f3b3b5f8cacdb4eee85778f637b67 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4800,9 +4800,7 @@ LLViewerTexture* LLViewerObject::getBakedTextureForMagicId(const LLUUID& id)
 	}
 
 	LLVOAvatar* avatar = getAvatar();
-	if (avatar && !isHUDAttachment()
-		&& isMesh()
-		&& getVolume() && getVolume()->getParams().getSculptID().notNull()) // checking for the rigged mesh by params instead of using isRiggedMesh() to avoid false negatives when skin info isn't ready
+	if (avatar && !isHUDAttachment())
 	{
 		LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id);
 		LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex);
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 12a9b47307ee5bc307cb715c9c97ea69c69e9b78..250c4ac32867d62071dc3e87a32e01d017d55d7d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -114,7 +114,7 @@ class LLViewerObject
 	public LLTrace::MemTrackable<LLViewerObject>
 {
 protected:
-	~LLViewerObject(); // use unref()
+	virtual ~LLViewerObject(); // use unref()
 
 	// TomY: Provide for a list of extra parameter structures, mapped by structure name
 	struct ExtraParameter
diff --git a/indra/newview/llviewerparcelaskplay.cpp b/indra/newview/llviewerparcelaskplay.cpp
index 74586dadc30c416d2665d78a21e25f0683b4d2e2..afbe2c94de8e56443501002fd6e2ce1a3a41db3e 100644
--- a/indra/newview/llviewerparcelaskplay.cpp
+++ b/indra/newview/llviewerparcelaskplay.cpp
@@ -59,7 +59,10 @@ void LLViewerParcelAskPlay::initSingleton()
 }
 void LLViewerParcelAskPlay::cleanupSingleton()
 {
-    cancelNotification();
+    if (LLNotifications::instanceExists())
+    {
+        cancelNotification();
+    }
 }
 
 void LLViewerParcelAskPlay::askToPlay(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, ask_callback cb)
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index a30c5156fab60b0bedaf46652c5bda7ad265ba94..5c99e693d2510cbcbbee62685174e9781749e702 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -291,6 +291,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
 
         LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url 
                                             << " region name " << regionp->getName()
+                                            << " handle " << regionp->getHandle()
                                             << " (attempt #" << mSeedCapAttempts + 1 << ")" << LL_ENDL;
 		LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL;
 
@@ -350,9 +351,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
         log_capabilities(mCapabilities);
 #endif
 
+        LL_DEBUGS("AppInit", "Capabilities", "Teleport") << "received caps for handle " << regionHandle 
+														 << " region name " << regionp->getName() << LL_ENDL;
         regionp->setCapabilitiesReceived(true);
-        LL_DEBUGS("AppInit", "Capabilities") << "received caps for handle " << regionHandle 
-                                             << " region name " << regionp->getName() << LL_ENDL;
 
         if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
         {
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index f108d9632073678d218eb13389e1b252cb4e3732..be5c22e7c3a65f30155f1ead83bbc36d815065e9 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -400,6 +400,15 @@ void LLViewerShaderMgr::setShaders()
         return;
     }
 
+    if (!gGLManager.mHasShaderObjects
+        || !gGLManager.mHasVertexShader
+        || !gGLManager.mHasFragmentShader)
+    {
+        // Viewer will show 'hardware requirements' warning later
+        LL_INFOS("ShaderLoading") << "Shaders not supported" << LL_ENDL;
+        return;
+    }
+
     static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
     LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 5b83cf7163edbeb10fb5c651c6f8b0d10780752d..bea4f2e4a5d4402289d558e1370a38ff0eab8250 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -346,6 +346,12 @@ class LLDebugText
 
 	void update()
 	{
+		if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+		{
+			clearText();
+			return;
+		}
+
 		static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
 
 		std::string wind_vel_text;
@@ -2317,7 +2323,7 @@ void LLViewerWindow::shutdownGL()
 LLViewerWindow::~LLViewerWindow()
 {
 	LL_INFOS() << "Destroying Window" << LL_ENDL;
-	gDebugWindowProc = TRUE; // event catching, at this point it shouldn't output at all
+	gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes
 	destroyWindow();
 
 	delete mDebugText;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index cc590fc947cf1b42d192942d468fda53656a963e..377f3174f3407930b5385debe2b9fb5518bfff9b 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -981,7 +981,12 @@ LLSpeakerVolumeStorage::LLSpeakerVolumeStorage()
 
 LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()
 {
-	save();
+}
+
+//virtual
+void LLSpeakerVolumeStorage::cleanupSingleton()
+{
+    save();
 }
 
 void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, F32 volume)
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 3d04e1f0dbe0c6c0e45734a2140ddc42753cddf7..1a4d253208227767c362f3012192d650e2d5efdc 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -499,9 +499,13 @@ class LLVoiceClient: public LLParamSingleton<LLVoiceClient>
  **/
 class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
 {
-	LLSINGLETON(LLSpeakerVolumeStorage);
+	LLSINGLETON_C11(LLSpeakerVolumeStorage);
 	~LLSpeakerVolumeStorage();
 	LOG_CLASS(LLSpeakerVolumeStorage);
+
+protected:
+    virtual void cleanupSingleton() override;
+
 public:
 
 	/**
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 976ef61d8ea32f4fa3d2d6511b56b410b62d8b4a..a8d668420e127dac98e2585601dd4b8f57b83151 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1744,6 +1744,12 @@ bool LLVivoxVoiceClient::waitForChannel()
             return false;
         }
 
+        if (sShuttingDown)
+        {
+            logoutOfVivox(true);
+            return false;
+        }
+
         if (LLVoiceClient::instance().getVoiceEffectEnabled())
         {
             retrieveVoiceFonts();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index ef39faa8142fabbc1f1e62a55c79c7a35ae01610..492d37edba9a2759b9cae0aab9537b27b58fe76d 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -235,7 +235,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
 	mLastFetchedMediaVersion = -1;
 	memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
 	mMDCImplCount = 0;
-    mLastRiggingInfoLOD = -1;
+	mLastRiggingInfoLOD = -1;
+	mResetDebugText = false;
 }
 
 LLVOVolume::~LLVOVolume()
@@ -1391,6 +1392,15 @@ BOOL LLVOVolume::calcLOD()
         {
             std::string debug_object_text = get_debug_object_lod_text(this);
             setDebugText(debug_object_text);
+            mResetDebugText = true;
+        }
+    }
+    else
+    {
+        if (mResetDebugText)
+        {
+            restoreHudText();
+            mResetDebugText = false;
         }
     }
 
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index de00ef494e65ea908d5adf1d7e600581544d6111..ce400a34986b8c2e56e32def745e354cfefb1a9c 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -424,6 +424,8 @@ class LLVOVolume : public LLViewerObject
 	S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
 	S32 mMDCImplCount;
 
+	bool mResetDebugText;
+
 	LLPointer<LLRiggedVolume> mRiggedVolume;
 
 	// statics
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index ccda92810e83d25263b3207ba5e099255ff94e1f..12def24a0dd47a8685d26bab957039ff464e5aaf 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -145,7 +145,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
 	static const unsigned int vertices_per_quad = 4;
 	static const unsigned int indices_per_quad = 6;
 
-	const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") && LLGLSLShader::sNoFixedFunction ? 16 : 1;
+	const S32 size = LLPipeline::sRenderTransparentWater && LLGLSLShader::sNoFixedFunction ? 16 : 1;
 
 	const S32 num_quads = size * size;
 	face->setSize(vertices_per_quad * num_quads,
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index e7bbee5efd9b9f3d1edda598b32de3c42b02f781..e7f62e77b46c030bda62815673ba31ef8416591b 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -38,6 +38,7 @@
 #include "llgesturemgr.h"
 #include "lltransutil.h"
 #include "llviewerattachmenu.h"
+#include "llviewermenu.h"
 #include "llvoavatarself.h"
 
 class LLFindOutfitItems : public LLInventoryCollectFunctor
@@ -794,7 +795,7 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
 	// Register handlers common for all wearable types.
 	registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
 	registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
-	registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
+	registrar.add("Wearable.Edit", boost::bind(handle_item_edit, selected_id));
 	registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
 	registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
 	registrar.add("Wearable.TakeOffDetach", 
@@ -809,6 +810,7 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
 	// Register handlers for attachments.
 	registrar.add("Attachment.Detach", 
 				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
+	registrar.add("Attachment.Touch", boost::bind(handle_attachment_touch, selected_id));
 	registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
 	registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
 
@@ -838,6 +840,7 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
 	U32 n_already_worn = 0;			// number of items worn of same type as selected items
 	U32 n_links = 0;				// number of links among the selected items
 	U32 n_editable = 0;				// number of editable items among the selected ones
+	U32 n_touchable = 0;            // number of touchable items among the selected ones
 
 	bool can_be_worn = true;
 
@@ -858,12 +861,17 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
 		const LLWearableType::EType wearable_type = item->getWearableType();
 		const bool is_link = item->getIsLinkType();
 		const bool is_worn = get_is_item_worn(id);
-		const bool is_editable = gAgentWearables.isWearableModifiable(id);
+		const bool is_editable = get_is_item_editable(id);
+		const bool is_touchable = enable_attachment_touch(id);
 		const bool is_already_worn = gAgentWearables.selfHasWearable(wearable_type);
 		if (is_worn)
 		{
 			++n_worn;
 		}
+		if (is_touchable)
+		{
+			++n_touchable;
+		}
 		if (is_editable)
 		{
 			++n_editable;
@@ -893,8 +901,10 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
 	setMenuItemEnabled(menu, "wear_add",			LLAppearanceMgr::instance().canAddWearables(ids));
 	setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0 && can_be_worn);
 	//visible only when one item selected and this item is worn
-	setMenuItemVisible(menu, "edit",				!standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1);
-	setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1 && n_items == 1);
+	setMenuItemVisible(menu, "touch",				!standalone && mask == MASK_ATTACHMENT && n_worn == n_items);
+	setMenuItemEnabled(menu, "touch",				n_touchable && n_worn == 1 && n_items == 1);
+	setMenuItemVisible(menu, "edit",				!standalone && mask & (MASK_CLOTHING|MASK_BODYPART|MASK_ATTACHMENT) && n_worn == n_items);
+	setMenuItemEnabled(menu, "edit",				n_editable && n_worn == 1 && n_items == 1);
 	setMenuItemVisible(menu, "create_new",			mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1);
 	setMenuItemEnabled(menu, "create_new",			LLAppearanceMgr::instance().canAddWearables(ids));
 	setMenuItemVisible(menu, "show_original",		!standalone);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 604c5f770de6783993d8c20d25a84d2c47f1d683..644934d1d84ac6c033eb1b6ed85ea582979b4bec 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -329,6 +329,7 @@ bool	LLPipeline::sDelayVBUpdate = true;
 bool	LLPipeline::sAutoMaskAlphaDeferred = true;
 bool	LLPipeline::sAutoMaskAlphaNonDeferred = false;
 bool	LLPipeline::sDisableShaders = false;
+bool	LLPipeline::sRenderTransparentWater = true;
 bool	LLPipeline::sRenderBump = true;
 bool	LLPipeline::sBakeSunlight = false;
 bool	LLPipeline::sNoAlpha = false;
@@ -1043,6 +1044,12 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
 	return true;
 }
 
+//static
+void LLPipeline::updateRenderTransparentWater()
+{
+    sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
+}
+
 //static
 void LLPipeline::updateRenderBump()
 {
@@ -1056,6 +1063,7 @@ void LLPipeline::updateRenderDeferred()
                       RenderDeferred &&
                       LLRenderTarget::sUseFBO &&
                       LLPipeline::sRenderBump &&
+                      LLPipeline::sRenderTransparentWater &&
                       RenderAvatarVP &&
                       WindLightUseAtmosShaders &&
                       (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
@@ -6053,25 +6061,18 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
 	{
 		return max_dist;
 	}
-	F32 radius = light->getLightRadius();
 	bool selected = light->isSelected();
-	LLVector3 dpos = light->getRenderPosition() - cam_pos;
-	F32 dist2 = dpos.lengthSquared();
-	if (!selected && dist2 > (max_dist + radius)*(max_dist + radius))
-	{
-		return max_dist;
-	}
-	F32 dist = (F32) sqrt(dist2);
-	dist *= 1.f / inten;
-	dist -= radius;
 	if (selected)
 	{
-		dist -= 10000.f; // selected lights get highest priority
+        return 0.f; // selected lights get highest priority
 	}
+    F32 radius = light->getLightRadius();
+    F32 dist = dist_vec(light->getRenderPosition(), cam_pos);
+    dist = llmax(dist - radius, 0.f);
 	if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
 	{
 		// moving lights get a little higher priority (too much causes artifacts)
-		dist -= light->getLightRadius()*0.25f;
+        dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
 	}
 	return dist;
 }
@@ -6090,13 +6091,18 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 		// mNearbyLight (and all light_set_t's) are sorted such that
 		// begin() == the closest light and rbegin() == the farthest light
 		const S32 MAX_LOCAL_LIGHTS = 6;
-// 		LLVector3 cam_pos = gAgent.getCameraPositionAgent();
-		LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
-						camera.getOrigin() : 
-						gAgent.getPositionAgent();
-
-		F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad
+        LLVector3 cam_pos = camera.getOrigin();
 		
+        F32 max_dist;
+        if (LLPipeline::sRenderDeferred)
+        {
+            max_dist = RenderFarClip;
+        }
+        else
+        {
+            max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f);
+        }
+
 		// UPDATE THE EXISTING NEARBY LIGHTS
 		light_set_t cur_nearby_lights;
 		for (light_set_t::iterator iter = mNearbyLights.begin();
@@ -6130,8 +6136,38 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				continue;
 			}
 
-			F32 dist = calc_light_dist(volight, cam_pos, max_dist);
-			cur_nearby_lights.insert(Light(drawable, dist, light->fade));
+            F32 dist = calc_light_dist(volight, cam_pos, max_dist);
+            F32 fade = light->fade;
+            // actual fade gets decreased/increased by setupHWLights
+            // light->fade value is 'time'.
+            // >=0 and light will become visible as value increases
+            // <0 and light will fade out
+            if (dist < max_dist)
+            {
+                if (fade < 0)
+                {
+                    // mark light to fade in
+                    // if fade was -LIGHT_FADE_TIME - it was fully invisible
+                    // if fade -0 - it was fully visible
+                    // visibility goes up from 0 to LIGHT_FADE_TIME.
+                    fade += LIGHT_FADE_TIME;
+                }
+            }
+            else
+            {
+                // mark light to fade out
+                // visibility goes down from -0 to -LIGHT_FADE_TIME.
+                if (fade >= LIGHT_FADE_TIME)
+                {
+                    fade = -0.0001f; // was fully visible
+                }
+                else if (fade >= 0)
+                {
+                    // 0.75 visible light should stay 0.75 visible, but should reverse direction
+                    fade -= LIGHT_FADE_TIME;
+                }
+            }
+            cur_nearby_lights.insert(Light(drawable, dist, fade));
 		}
 		mNearbyLights = cur_nearby_lights;
 				
@@ -6150,17 +6186,23 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 			{
 				continue; // no lighting from HUD objects
 			}
-			F32 dist = calc_light_dist(light, cam_pos, max_dist);
-			if (dist >= max_dist)
+            if (!sRenderAttachedLights && light && light->isAttachment())
 			{
 				continue;
 			}
-			if (!sRenderAttachedLights && light && light->isAttachment())
+            LLVOAvatar * av = light->getAvatar();
+            if (av && (av->isTooComplex() || av->isInMuteList()))
+            {
+                // avatars that are already in the list will be removed by removeMutedAVsLights
+                continue;
+            }
+            F32 dist = calc_light_dist(light, cam_pos, max_dist);
+            if (dist >= max_dist)
 			{
 				continue;
 			}
 			new_nearby_lights.insert(Light(drawable, dist, 0.f));
-			if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
+            if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
 			{
 				new_nearby_lights.erase(--new_nearby_lights.end());
 				const Light& last = *new_nearby_lights.rbegin();
@@ -6173,7 +6215,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 			 iter != new_nearby_lights.end(); iter++)
 		{
 			const Light* light = &(*iter);
-			if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
+            if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
 			{
 				mNearbyLights.insert(*light);
 				((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
@@ -6186,10 +6228,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
 				if (light->dist < farthest_light->dist)
 				{
-					if (farthest_light->fade >= 0.f)
-					{
-						farthest_light->fade = -(gFrameIntervalSeconds.value());
-					}
+                    // mark light to fade out
+                    // visibility goes down from -0 to -LIGHT_FADE_TIME.
+                    //
+                    // This is a mess, but for now it needs to be in sync
+                    // with fade code above. Ex: code above detects distance < max,
+                    // sets fade time to positive, this code then detects closer
+                    // lights and sets fade time negative, fully compensating
+                    // for the code above
+                    if (farthest_light->fade >= LIGHT_FADE_TIME)
+                    {
+                        farthest_light->fade = -0.0001f; // was fully visible
+                    }
+                    else if (farthest_light->fade >= 0)
+                    {
+                        farthest_light->fade -= LIGHT_FADE_TIME;
+                    }
 				}
 				else
 				{
@@ -6309,12 +6363,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
                 }
             }
 
-            const LLViewerObject *vobj = drawable->getVObj();
-            if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList())
-            {
-                continue;
-            }
-
 			if (drawable->isState(LLDrawable::ACTIVE))
 			{
 				mLightMovingMask |= (1<<cur_light);
@@ -8686,11 +8734,13 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
                 mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
                 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-                for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
+                // mNearbyLights already includes distance calculation and excludes muted avatars.
+                // It is calculated from mLights
+                // mNearbyLights also provides fade value to gracefully fade-out out of range lights
+                for (light_set_t::iterator iter = mNearbyLights.begin(); iter != mNearbyLights.end(); ++iter)
                 {
-                    LLDrawable *drawablep = *iter;
-
-                    LLVOVolume *volume = drawablep->getVOVolume();
+                    LLDrawable * drawablep = iter->drawable;
+                    LLVOVolume * volume = drawablep->getVOVolume();
                     if (!volume)
                     {
                         continue;
@@ -8704,24 +8754,8 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
                         }
                     }
 
-                    const LLViewerObject *vobj = drawablep->getVObj();
-                    if (vobj)
-                    {
-                        LLVOAvatar *av = vobj->getAvatar();
-                        if (av && (av->isTooComplex() || av->isInMuteList()))
-                        {
-                            continue;
-                        }
-                    }
-
-                    const LLVector3 position = drawablep->getPositionAgent();
-                    if (dist_vec(position, LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip + volume->getLightRadius())
-                    {
-                        continue;
-                    }
-
                     LLVector4a center;
-                    center.load3(position.mV);
+                    center.load3(drawablep->getPositionAgent().mV);
                     const F32 *c = center.getF32ptr();
                     F32        s = volume->getLightRadius() * 1.5f;
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 600bdd9d06dc1aba6baba86a462f9fca789267ea..52fd51cd80d9375a7efa6d3bd8275f662c7d03a4 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -409,6 +409,7 @@ class LLPipeline
 	static bool getRenderHighlights();
 	static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
 
+	static void updateRenderTransparentWater();
 	static void updateRenderBump();
 	static void updateRenderDeferred();
 	static void refreshCachedSettings();
@@ -578,6 +579,7 @@ class LLPipeline
 	static bool				sAutoMaskAlphaDeferred;
 	static bool				sAutoMaskAlphaNonDeferred;
 	static bool				sDisableShaders; // if true, rendering will be done without shaders
+	static bool				sRenderTransparentWater;
 	static bool				sRenderBump;
 	static bool				sBakeSunlight;
 	static bool				sNoAlpha;
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index 8587243791274c274b45b67015b5392b5e8133e3..ff2d8b4943abfa9f26144b80c46a82621bc6b8fe 100755
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -155,7 +155,7 @@ BEGIN
             VALUE "FileDescription", "Second Life"
             VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
             VALUE "InternalName", "Second Life"
-            VALUE "LegalCopyright", "Copyright � 2001, Linden Research, Inc."
+            VALUE "LegalCopyright", "Copyright (c) 2020, Linden Research, Inc."
             VALUE "OriginalFilename", "SecondLife.exe"
             VALUE "ProductName", "Second Life"
             VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7869eb7267d1ee70ccaf755ee49c48462b50aab7..f44cc544183ebf9cf3a0da20e0bf544bb8af731d 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -41,6 +41,9 @@
 	<color
 	 name="Gray"
 	 value="0.5 0.5 0.5 1" />
+	<color
+	 name="DkGray0"
+	 value="0.27 0.27 0.27 1" />
 	<color
 	 name="DkGray"
 	 value="0.125 0.125 0.125 1" />
diff --git a/indra/newview/skins/default/xui/da/menu_cof_attachment.xml b/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
index 9d7fc0f2239d0c679c0d58a467b57fb1ec212a04..37e9351ab52baa72c7d3d4b20d484aa9a643418e 100644
--- a/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Berør" name="touch_attach" />
+	<menu_item_call label="Redigér" name="edit_item" />
 	<menu_item_call label="Tag af" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/da/menu_inventory.xml b/indra/newview/skins/default/xui/da/menu_inventory.xml
index f9bdf36f1fece9c0a9810de07ba92d34e10ca822..ba96d6dca1a136eeb1f63c4a63a40f899bb1bc62 100644
--- a/indra/newview/skins/default/xui/da/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/da/menu_inventory.xml
@@ -78,6 +78,7 @@
 	<menu_item_call label="Tag på" name="Wearable And Object Wear"/>
 	<menu label="Vedhæft" name="Attach To"/>
 	<menu label="Vedhæft til HUD" name="Attach To HUD"/>
+	<menu_item_call label="Berør" name="Attachment Touch" />
 	<menu_item_call label="Redigér" name="Wearable Edit"/>
 	<menu_item_call label="Tilføj" name="Wearable Add"/>
 	<menu_item_call label="Tag af" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
index 63f4b0b38849cdb60770137ef4f52f64a5879c12..67adf74bcd3644ffb6591c0f35087460738b488a 100644
--- a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Erstat" name="wear_replace"/>
 	<menu_item_call label="Tag på" name="wear_wear"/>
 	<menu_item_call label="Tilføj" name="wear_add"/>
+	<menu_item_call label="Berør" name="touch" />
 	<menu_item_call label="Tag af" name="take_off_or_detach"/>
 	<menu_item_call label="Tag af" name="detach"/>
 	<context_menu label="Vedhæft til" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/da/menu_wearing_gear.xml b/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
index 515a15b287ea9a122af3176b1bc8cab204cbbbcc..ff58cd68b2f59a467c271d0fc2105eb5f798d28b 100644
--- a/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <menu name="Gear Wearing">
-	<menu_item_call label="Redigér sæt" name="edit"/>
+	<menu_item_call label="Berør" name="touch"/>
+	<menu_item_call label="Redigér" name="edit_item"/>
+	<menu_item_call label="Redigér sæt" name="edit_outfit"/>
 	<menu_item_call label="Tag af" name="takeoff"/>
 </menu>
diff --git a/indra/newview/skins/default/xui/da/menu_wearing_tab.xml b/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
index c0db7b68426012c915339b32dfd5093ae60ea9d9..adaac35f68e4f9d347245393cb6675dba8322d90 100644
--- a/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Berør" name="touch_attach"/>
+	<menu_item_call label="Redigér" name="edit_item"/>
 	<menu_item_call label="Tag af" name="take_off"/>
 	<menu_item_call label="Tag af" name="detach"/>
-	<menu_item_call label="Redigér sæt" name="edit"/>
+	<menu_item_call label="Redigér sæt" name="edit_outfit"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_cof_attachment.xml b/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
index 05d3dfca9dde987eaa946f2ceb6b7bc15e254246..7c7da5886640dc0bd1b83738915a0a2025fe7173 100644
--- a/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Berühren" name="touch_attach" />
+	<menu_item_call label="Bearbeiten" name="edit_item" />
 	<menu_item_call label="Abnehmen" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml
index 84cded77ce7f3ab4790552cdc674defc3d3ce121..743b8b20730578d8a897b8a3b3affaaaa7a940d2 100644
--- a/indra/newview/skins/default/xui/de/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="Anziehen" name="Wearable And Object Wear"/>
 	<menu label="Anhängen an" name="Attach To"/>
 	<menu label="An HUD hängen" name="Attach To HUD"/>
+	<menu_item_call label="Berühren" name="Attachment Touch" />
 	<menu_item_call label="Bearbeiten" name="Wearable Edit"/>
 	<menu_item_call label="Hinzufügen" name="Wearable Add"/>
 	<menu_item_call label="Ausziehen" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
index 283e454a0647b72b3c9527ba00edc61d4ab5599c..e4c2c88f11b6b31a06c0067fc3c4db66f78ecdf9 100644
--- a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Ersetzen" name="wear_replace"/>
 	<menu_item_call label="Anziehen" name="wear_wear"/>
 	<menu_item_call label="Hinzufügen" name="wear_add"/>
+	<menu_item_call label="Berühren" name="touch" />
 	<menu_item_call label="Ausziehen / Abnehmen" name="take_off_or_detach"/>
 	<menu_item_call label="Abnehmen" name="detach"/>
 	<context_menu label="Anhängen an" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
index dacf898b6a4231578cdade8cd38a556c931f97c0..6cb0d095e7ad58ea660a983b783c52c49a82230e 100644
--- a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Outfit bearbeiten" name="edit"/>
+	<menu_item_call label="Berühren" name="touch"/>
+	<menu_item_call label="Bearbeiten" name="edit_item"/>
+	<menu_item_call label="Outfit bearbeiten" name="edit_outfit"/>
 	<menu_item_call label="Ausziehen" name="takeoff"/>
 	<menu_item_call label="Outfitliste in Zwischenablage kopieren" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
index 61002b3dad2564f0c889b300467c6be68c022c32..c729ef6b0042890aad267f6d8b15d4b184a8ca2c 100644
--- a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Berühren" name="touch_attach"/>
 	<menu_item_call label="Ausziehen" name="take_off"/>
 	<menu_item_call label="Abnehmen" name="detach"/>
-	<menu_item_call label="Outfit bearbeiten" name="edit"/>
+	<menu_item_call label="Outfit bearbeiten" name="edit_outfit"/>
 	<menu_item_call label="Bearbeiten" name="edit_item"/>
 	<menu_item_call label="Original anzeigen" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index a5a05f7de038a547f6250659a19fc61f4a4c5820..a72784f70b99be930ca08008d3d9f9d3bed3e769 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -266,6 +266,10 @@ Möchten Sie den ausgewählten Einwohnern Änderungsrechte gewähren?
 		Möchten Sie den ausgewählten Einwohnern die Änderungsrechte entziehen?
 		<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		Ein Gruppenname muss zwischen [MIN_LEN] und [MAX_LEN] Zeichen lang sein.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		Gruppe konnte nicht erstellt werden.
 [MESSAGE]
@@ -366,7 +370,7 @@ Fortfahren?
 Sie haben nicht genug L$, um dieser Gruppe beizutreten.
 	</notification>
 	<notification name="CreateGroupCost">
-		Die Gründung dieser Gruppe kostet 100 L$.
+		Die Erstellung dieser Gruppe kostet L$[COST].
 Gruppen müssen mehr als ein Mitglied haben oder sie werden gelöscht.
 Bitte laden Sie innerhalb von 48 Stunden Mitglieder in Ihre Gruppe ein.
 		<usetemplate canceltext="Abbrechen" name="okcancelbuttons" notext="Abbrechen" yestext="Gruppe für 100 L$ erstellen"/>
@@ -508,6 +512,9 @@ Um Medien nur auf einer Fläche einzufügen, wählen Sie „Oberfläche auswähl
 	<notification name="ErrorEncodingSnapshot">
 		Fehler beim Erstellen des Fotos!
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Du brauchst L$[COST], um diesen Artikel hochzuladen.
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Es kostet L$[COST], um ein Foto in Ihrem Inventar zu speichern. Sie können entweder L$ kaufen oder das Foto auf Ihrem Computer speichern.
 	</notification>
@@ -1753,11 +1760,14 @@ Diese Gruppe verlassen?
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		Die Gruppenbegrenzung für Basiskonten ist [MAX_BASIC]; für 
-[https://secondlife.com/premium/ Premium-]Konten ist sie [MAX_PREMIUM].
-Wenn Sie ein Downgrade Ihres Kontos durchgeführt haben, müssen Sie das Gruppenlimit unter [MAX_BASIC] bringen, bevor sich weitere Personen registrieren können.
-
-[https://secondlife.com/my/account/membership.php Noch heute upgraden!]
+		Einwohner mit Basic-Mitgliedschaft können bis zu [MAX_BASIC] Gruppen beitreten.
+Premium-Mitgliedschaften erlauben bis zu [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Mehr Informationen oder Upgrade]
+		<usetemplate name="okbutton" yestext="Schließen"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		Einwohner mit Basic-Mitgliedschaft können bis zu [MAX_BASIC] Gruppen beitreten.
+Premium-Mitgliedschaften erlauben bis zu [MAX_PREMIUM]. Premium-Plus-Mitgliedschaften 
+erlauben bis zu [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Mehr Informationen oder Upgrade]
 		<usetemplate name="okbutton" yestext="Schließen"/>
 	</notification>
 	<notification name="KickUser">
@@ -3323,6 +3333,22 @@ Diese werden für ein paar Sekunden sicherheitshalber gesperrt.
 		Sie wurden vom Moderator stummgeschaltet.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		Leider konnten wir für diese Sitzung keine Informationen zu den Leistungen erhalten. Dies sollte in einer normalen Produktionsumgebung nicht passieren. Kontaktiere bitte den Support. Diese Sitzung wird nicht normal laufen, und wir empfehlen, die Sitzung neu zu starten.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		Dadurch werden [COUNT] Artikel zu einem Gesamtpreis von L$[COST] hochgeladen. Möchtest du mit dem Hochladen fortfahren?
+		<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Hochladen"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		Ausgewählte Dateien können nicht per Bulk-Upload hochgeladen werden.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Einige der ausgewählten Dateien können nicht per Bulk-Upload hochgeladen werden.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		Das Hochladen kostet [PRICE] L$. Möchten Sie fortfahren?
 		<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Hochladen"/>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index d16b01157747fced807930003a2abe8fe1cfd957..e4a4c1033ec1fce3f760852739f5a641c67a1ab6 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -18,7 +18,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
 	<string name="no_groups_msg" value="Suchen Sie nach Gruppen? Versuchen Sie es mit der [secondlife:///app/search/groups Suche]."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Doppelklicken, um Karte zu öffnen; Umschalttaste gedrückt halten und ziehen, um zu schwenken)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Doppelklicken, um zu teleportieren; Umschalttaste gedrückt halten und ziehen, um zu schwenken)"/>
-	<string name="GroupCountWithInfo" value="Sie gehören [COUNT] Gruppen an und können [REMAINING] weiteren beitreten.  [secondlife:/// Möchten Sie noch mehr?]"/>
+	<string name="GroupCountWithInfo" value="Du gehörst zu [COUNT] Gruppen, und kannst [REMAINING] weiteren beitreten. [secondlife:/// Erhöhe dein Limit]"/>
 	<tab_container name="tabs">
 		<panel label="IN DER NÄHE" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
 				<dnd_button name="minus_btn" tool_tip="Ausgewählte Gruppe verlassen"/>
 			</panel>
 			<text name="groupcount">
-				Sie gehören [COUNT] Gruppen an und können [REMAINING] weiteren beitreten.
+				Du gehörst zu [COUNT] Gruppen, und kannst [REMAINING] weiteren beitreten.
 			</text>
 		</panel>
 		<panel label="AKTUELL" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 5f216895ae317451b3f2396d673019576945e24b..4762e262bd5f782b9e163bb55eff87b756bea592 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -1663,11 +1663,14 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
 	<string name="MarketplaceUpdating">
 		Aktualisierung läuft...
 	</string>
+	<string name="UploadFeeInfo">
+		Die Gebühr richtet sich nach deiner Abonnementstufe. Bei höheren Stufen werden niedrigere Gebühren erhoben. [https://secondlife.com/my/account/membership.php? Mehr erfahren]
+	</string>
 	<string name="Open landmarks">
-		Landmarken öffnen
+		Wegweiser öffnen
 	</string>
 	<string name="Unconstrained">
-		Variabel
+		Unbegrenzt
 	</string>
 	<string name="no_transfer" value=" (kein Transferieren)"/>
 	<string name="no_modify" value=" (kein Bearbeiten)"/>
@@ -5129,6 +5132,15 @@ Bitte überprüfen Sie http://status.secondlifegrid.net, um herauszufinden, ob e
 	<string name="Chat" value=" Chat:">
 		Chat
 	</string>
+	<string name="BaseMembership">
+		Basis
+	</string>
+	<string name="PremiumMembership">
+		Premium
+	</string>
+	<string name="Premium PlusMembership">
+		Premium Plus
+	</string>
 	<string name="DeleteItems">
 		Ausgewählte Objekte löschen?
 	</string>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index e93568a87e59d11f122ce63948b7c0c487adf52f..e282f1b179c10935c715565147af7fa0d5aa77d9 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -596,7 +596,10 @@
     left="420"
     name="TransparentWater"
     top_delta="16"
-    width="300" />
+    width="300">
+    <check_box.commit_callback
+      function="Pref.RenderOptionUpdate" />
+  </check_box>
 
   <check_box
     control_name="RenderObjectBump"
diff --git a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
index c402100fb1e713cadc8a6b49dc35278aaeb4dbed..3f545c936d5733147a8b2dd7090b46390f0873fb 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
@@ -2,6 +2,26 @@
 <context_menu
  layout="topleft"
  name="COF Attachment">
+    <menu_item_call
+     label="Touch"
+     layout="topleft"
+     name="touch_attach">
+        <on_click
+         function="Attachment.Touch" />
+        <on_enable
+         function="Attachment.OnEnable"
+         parameter="touch" />
+    </menu_item_call>
+    <menu_item_call
+     label="Edit"
+     layout="topleft"
+     name="edit_item">
+        <on_click
+         function="Attachment.Edit" />
+        <on_enable
+         function="Attachment.OnEnable"
+         parameter="edit" />
+   </menu_item_call>
     <menu_item_call
      label="Detach"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 9aa84c1bac4e5746e0403b234d8ad71d7d8618d0..eda97399765fc9023156adedb2da3a52fab47f42 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -810,14 +810,6 @@
     <menu_item_separator
      layout="topleft" 
      name="Wearable And Object Separator"/>
-    <menu_item_call
-     label="Detach From Yourself"
-     layout="topleft"
-     name="Detach From Yourself">
-        <menu_item_call.on_click
-         function="Inventory.DoToSelected"
-         parameter="detach" />
-    </menu_item_call>
 	<!-- COMMENTED OUT for DEV-32347 -->
 	<!--
     <menu_item_call
@@ -845,6 +837,14 @@
      label="Attach To HUD"
      layout="topleft"
      name="Attach To HUD" />
+    <menu_item_call
+     label="Touch"
+     layout="topleft"
+     name="Attachment Touch">
+        <menu_item_call.on_click
+         function="Inventory.DoToSelected"
+         parameter="touch" />
+    </menu_item_call>
     <menu_item_call
      label="Edit"
      layout="topleft"
@@ -861,6 +861,14 @@
          function="Inventory.DoToSelected"
          parameter="wear_add" />
     </menu_item_call>
+    <menu_item_call
+     label="Detach From Yourself"
+     layout="topleft"
+     name="Detach From Yourself">
+        <menu_item_call.on_click
+         function="Inventory.DoToSelected"
+         parameter="detach" />
+    </menu_item_call>
     <menu_item_call
      label="Take Off"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
index aa56b4ba63c2d730710c781ec6e34780935776ca..cb429812e22c0a2c06acdd75735c9dc491744224 100644
--- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
@@ -22,6 +22,18 @@
         <on_click
          function="Wearable.Add" />
     </menu_item_call>
+    <menu_item_call
+     label="Touch"
+     layout="topleft"
+     name="touch"
+     on_click.function="Attachment.Touch"
+     />
+    <menu_item_call
+     label="Edit"
+     layout="topleft"
+     name="edit"
+     on_click.function="Wearable.Edit"
+     />
     <menu_item_call
      label="Take Off / Detach"
      layout="topleft"
@@ -51,13 +63,6 @@
         <on_click
          function="Clothing.TakeOff" />
     </menu_item_call>
-    <menu_item_call
-     label="Edit"
-     layout="topleft"
-     name="edit">
-        <on_click
-         function="Wearable.Edit" />
-    </menu_item_call>
     <menu_item_call
      label="Item Profile"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
index 0e858ccf107f34dda72b12467fe1b86587d7cd84..57b20dfda9167ef7a00ccb71e77ab96ea1c508ab 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
@@ -4,11 +4,24 @@
  visible="false"
  name="Gear Wearing">
     <menu_item_call
-     label="Edit Outfit"
+     label="Touch"
+     layout="topleft"
+     name="touch">
+        <on_click
+         function="Gear.TouchAttach" />
+        <on_enable
+         function="Gear.OnEnable"
+         parameter="touch_attach" />
+    </menu_item_call>
+    <menu_item_call
+     label="Edit"
      layout="topleft"
-     name="edit">
+     name="edit_item">
         <on_click
-         function="Gear.Edit" />
+         function="Gear.EditItem" />
+        <on_enable
+         function="Gear.OnEnable"
+         parameter="edit_item" />
     </menu_item_call>
     <menu_item_call
      label="Take Off"
@@ -20,6 +33,14 @@
          function="Gear.OnEnable"
          parameter="take_off" />
     </menu_item_call>
+    <menu_item_separator />
+    <menu_item_call
+     label="Edit Outfit"
+     layout="topleft"
+     name="edit_outfit">
+        <on_click
+         function="Gear.EditOutfit" />
+    </menu_item_call>
     <menu_item_call
      label="Copy outfit list to clipboard"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
index 75c1de24aa229a2f68c2698b3cdbc22c7d632e29..b8e2b448843f9b10998b7f355980b109e59e1d61 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
@@ -2,6 +2,20 @@
 <context_menu
  layout="topleft"
  name="Wearing">
+    <menu_item_call
+     label="Touch"
+     layout="topleft"
+     name="touch_attach">
+        <on_click
+         function="Wearing.TouchAttach" />
+    </menu_item_call>
+    <menu_item_call
+     label="Edit"
+     layout="topleft"
+     name="edit_item">
+        <on_click
+         function="Wearing.EditItem" />
+    </menu_item_call>
     <menu_item_call
      label="Take Off"
      layout="topleft"
@@ -23,16 +37,9 @@
     <menu_item_call
      label="Edit Outfit"
      layout="topleft"
-     name="edit">
+     name="edit_outfit">
         <on_click
-         function="Wearing.Edit" />
-    </menu_item_call>
-    <menu_item_call
-     label="Edit"
-     layout="topleft"
-     name="edit_item">
-        <on_click
-         function="Wearing.EditItem" />
+         function="Wearing.EditOutfit" />
     </menu_item_call>
     <menu_item_call
      label="Show Original"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a0d56a0d083f876515449652ed8244776ef94217..29d570de647b8e19c36152c7185e9ce79a7a21a2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3186,7 +3186,7 @@ Do you want to remove multiple friends from your Friends list?
    type="alertmodal">
 Are you sure you want to delete all scripted objects owned by
 ** [AVATAR_NAME] **
-on all others land in this sim?
+on all others land in this region?
     <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
@@ -3200,7 +3200,7 @@ on all others land in this sim?
    type="alertmodal">
 Are you sure you want to DELETE ALL scripted objects owned by
 ** [AVATAR_NAME] **
-on ALL LAND in this sim?
+on ALL LAND in this region?
     <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
@@ -3214,7 +3214,7 @@ on ALL LAND in this sim?
    type="alertmodal">
 Are you sure you want to DELETE ALL objects (scripted or not) owned by
 ** [AVATAR_NAME] **
-on ALL LAND in this sim?
+on ALL LAND in this region?
     <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
@@ -9568,6 +9568,12 @@ Do you wish to continue?
      yestext="OK"/>
   </notification>
 
+  <global name="UnsupportedShaderRequirements">
+You do not appear to meet the hardware requirements for [APP_NAME]. [APP_NAME] requires OpenGL 2.0 or later shader support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
+
+If you continue to have problems, please visit the [SUPPORT_SITE].
+  </global>
+
   <global name="UnsupportedGLRequirements">
 You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
 
@@ -10290,7 +10296,7 @@ Unable to add script!
    name="AssetServerTimeoutObjReturn"
    type="notify">
    <tag>fail</tag>
-Asset server didn't respond in a timely fashion.  Object returned to sim.
+Asset server didn't respond in a timely fashion.  Object returned to the region.
   </notification>
 
   <notification
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 87035e5cd38e83c57919772559d56fdcc30bd6c8..7935d66aee555f3bd3df75aca1c72c5d2d42c21f 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -95,7 +95,7 @@
         <panel
          bg_alpha_color="DkGray2"
          follows="left|top|right"
-         height="630"
+         height="654"
          layout="topleft"
          left="0"
          min_height="300"
@@ -112,35 +112,56 @@
              name="logo"
              top="10"
              width="290" />
+            <!-- texture picker has an empty label section, compensate for it with negative top_pad-->
             <text
              follows="left|top|right"
              font="SansSerifLarge"
              height="14"
              layout="topleft"
              left="10"
-             name="region_title"
+             top_pad="-10"
+             width="280"
+             name="parcel_title"
              text_color="white"
-             top_pad="10"
              use_ellipses="true"
-             value="SampleRegion"
-             width="280" />
+             value="SampleParcel, Name Long" />
             <text
              follows="left|top|right"
              height="14"
              layout="topleft"
              left="10"
-             name="parcel_title"
-             top_pad="10"
+             top_pad="9"
+             width="280"
+             name="region_title"
+             use_ellipses="true">
+              Region: [REGIONAMEPOS]
+            </text>
+            <text
+             follows="left|top"
+             height="15"
+             layout="topleft"
+             left="10"
+             name="parcel_owner_label"
+             top_pad="7"
+             value="Owner:"
+             width="80" />
+            <text
+             follows="left|top|right"
+             height="15"
+             layout="topleft"
+             left_pad="0"
+             name="parcel_owner"
+             top_delta="0"
              use_ellipses="true"
-             value="SampleParcel, Name Long (145, 228, 26)"
-             width="280" />
+             value="TempOwner"
+             width="215" />
             <expandable_text
              follows="left|top|right"
              height="50"
              layout="topleft"
              left="10"
              name="description"
-             top_pad="10"
+             top_pad="7"
              value="Du waltz die spritz"
              width="280" />
             <icon
@@ -163,19 +184,38 @@
              width="268" />
             <panel
              follows="left|top|right"
-             height="55"
+             height="81"
              layout="topleft"
              left="10"
              name="landmark_info_panel"
              top_pad="10"
              width="290">
+                <view_border
+                 bevel_style="none"
+                 follows="top|left"
+                 height="0"
+                 layout="topleft"
+                 left="0"
+                 name="lod_tab_border"
+                 top_pad="5"
+                 width="290" />
+                <text
+                 follows="left|top"
+                 height="15"
+                 layout="topleft"
+                 left="0"
+                 name="this_landmark"
+                 top_pad="8"
+                 width="90">
+                  This landmark:
+                </text>
                 <text
                  follows="left|top"
                  height="15"
                  layout="topleft"
                  left="0"
                  name="owner_label"
-                 top_pad="10"
+                 top_pad="8"
                  value="Owner:"
                  width="90" />
                 <text
@@ -237,9 +277,13 @@
                  top_pad="10"
                  value="Title:"
                  width="290" />
-                <text
+                <line_editor
+                 text_readonly_color="white"
+                 enabled="false"
+                 use_bg_color="true"
+                 bg_color="DkGray0"
                  parse_urls="false"
-                 follows="left|top"
+                 follows="left|top|right"
                  height="22"
                  layout="topleft"
                  left="0"
@@ -269,7 +313,7 @@
                  value="My notes:"
                  width="290" />
                 <text_editor
-                 bg_readonly_color="DkGray2"
+                 bg_readonly_color="DkGray0"
                  follows="all"
                  height="75"
                  layout="topleft"
@@ -300,6 +344,17 @@
                  name="folder_combo"
                  top_pad="5"
                  width="200" />
+                <button
+                 follows="bottom|left|right"
+                 height="23"
+                 label="Edit"
+                 layout="topleft"
+                 left="0"
+                 mouse_opaque="false"
+                 name="edit_btn"
+                 tool_tip="Edit landmark information"
+                 top_pad="-42"
+                 width="100" />
             </panel>
         </panel>
     </scroll_container>
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 0dd75b1b553131f8781d8d057ce923ba49b76ef2..36b7b0501b8b402491f1d0af3cd5f9d1e0442dbc 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -200,7 +200,7 @@
         <panel
          bg_alpha_color="DkGray2"
          follows="left|top|right|bottom"
-         height="580"
+         height="597"
          layout="topleft"
          left="0"
          min_height="300"
@@ -277,32 +277,25 @@
              height="14"
              layout="topleft"
              left="10"
-             name="region_title"
-             text_color="white"
              top_pad="5"
+             width="290"
+             name="parcel_title"
+             text_color="white"
              use_ellipses="true"
-             value="SampleRegion"
-             width="290" />
+             value="SampleParcel" />
             <text
              parse_urls="false"
              follows="left|top|right"
              height="14"
              layout="topleft"
              left="10"
-             name="parcel_title"
-             top_pad="4"
-             use_ellipses="true"
-             value="SampleParcel, Name Long (145, 228, 26)"
-             width="285" />
-            <expandable_text
-             follows="left|top"
-             height="50"
-             layout="topleft"
-             left="5"
-             name="description"
-             top_pad="10"
-             value="Du waltz die spritz"
-             width="285" />
+             top_pad="5"
+             width="285"
+             name="region_title"
+             text_color="White"
+             use_ellipses="true">
+              Region: [REGIONAMEPOS]
+            </text>
             <text
              follows="left|top"
              height="14"
@@ -310,20 +303,28 @@
              left="10"
              name="owner_label"
              text_color="White"
-             top_pad="0"
+             top_pad="2"
              value="Owner:"
-             width="90" />
-         <!--TODO: HOOK THIS NAME UP WITH AN INSPECTOR  -->
+             width="80" />
             <text
              follows="left|top|right"
              height="14"
              layout="topleft"
-             left_pad="1"
-             name="owner_value"
+             left_pad="0"
+             name="parcel_owner"
              top_delta="0"
              value="Alex Superduperlongenamenton"
              use_ellipses="true" 
              width="200" />
+            <expandable_text
+             follows="left|top"
+             height="50"
+             layout="topleft"
+             left="5"
+             name="description"
+             top_pad="10"
+             value="Du waltz die spritz"
+             width="285" />
             <icon
              follows="top|left"
              height="16"
@@ -331,7 +332,7 @@
              layout="topleft"
              left="10"
              name="maturity_icon"
-             top_delta="0"
+             top_pad="0"
              width="18" />
             <text
              follows="left|top|right"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 7d171490e852b1591184abc602e570be7f7b6db7..1f32ae53baec8591f3a5232df25c2819039de366 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -82,6 +82,7 @@ background_visible="true"
 		layout="topleft"
 		mouse_opaque="false"
 		name="bottom_bar_ls0"
+		animate="false"
 		left="4"
 		orientation="horizontal"
 		top="0"
@@ -150,8 +151,32 @@ background_visible="true"
 				         width="85" />		
 					</layout_panel>
 				</layout_stack>
-			</layout_panel>	
-			
+			</layout_panel>
+				 <!--*********************** Options button ***********************-->
+			<layout_panel
+				follows="bottom|right"
+				height="23"
+				layout="bottomleft"
+				left_pad="0"
+				mouse_opaque="false"
+				visible="false"
+				name="lp_options"
+				auto_resize="false"
+				width="23">
+				<menu_button
+					follows="bottom|right"
+					height="23"
+					image_disabled="ComboButton_UpOff"
+					image_unselected="ComboButton_UpOff"
+					image_selected="ComboButton_UpSelected"
+					layout="topleft"
+					mouse_opaque="false"
+					name="overflow_btn"
+					tool_tip="Show additional options"
+					top="0"
+					left="0"
+					width="23" />
+			</layout_panel>
 			<layout_panel
 			follows="bottom|left|right"
 			height="23"
@@ -159,69 +184,9 @@ background_visible="true"
 			left_pad="0"			
 			mouse_opaque="false"
 			name="lp2"
-		    auto_resize="true"
+			auto_resize="true"
 			width="116">
-			
-		<!--*********************** Edit, Options buttons ***********************-->		
-		
-				<layout_stack
-		     	follows="bottom|left|right"
-				height="23"
-				layout="topleft"
-				mouse_opaque="false"
-				name="bottom_bar_ls3"
-				left="0"
-				orientation="horizontal"
-				top="0"
-				width="113">
-		
-					<layout_panel
-					follows="bottom|left|right"
-					height="23"
-					layout="bottomleft"
-					left_pad="0"
-					mouse_opaque="false"
-					name="edit_btn_lp"
-				    auto_resize="true"
-					width="84">
-						<button
-				         follows="bottom|left|right"
-				         height="23"
-				         label="Edit"
-				         layout="topleft"
-				         left="1"
-						 mouse_opaque="false"
-				         name="edit_btn"
-				         tool_tip="Edit landmark information"
-				         top="0"
-				         width="83" />
-					</layout_panel>
-					
-					<layout_panel
-					follows="bottom|right"
-					height="23"
-					layout="bottomleft"
-					left_pad="0"
-					mouse_opaque="false"
-					name="overflow_btn_lp"
-				    auto_resize="true"
-					width="24">
-						<menu_button
-				         follows="bottom|right"
-				         height="23"
-						 image_disabled="ComboButton_UpOff"
-						 image_unselected="ComboButton_UpOff"
-						 image_selected="ComboButton_UpSelected"
-				         layout="topleft"
-						 mouse_opaque="false"
-				         name="overflow_btn"
-				         tool_tip="Show additional options"
-				         top="0"
-				         left="1"		         
-				         width="23" />			
-					</layout_panel>
-				</layout_stack>
-		
+
 		<!--*********************** Profile button ***********************-->		
 				
 				<layout_stack
diff --git a/indra/newview/skins/default/xui/es/menu_cof_attachment.xml b/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
index 7541530601dbd45ac04f9a2ba383c98a1f412535..65e31c0654828cd8e8c4c1df8c3e56e07de8ee0f 100644
--- a/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Tocar" name="touch_attach" />
+	<menu_item_call label="Editar" name="edit_item" />
 	<menu_item_call label="Quitar" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml
index c426158d3e69e8171140451913a258c1e06d3e29..d855d6f04fe2e16430b02cdfdcc19cf7a4bbae69 100644
--- a/indra/newview/skins/default/xui/es/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory.xml
@@ -104,6 +104,7 @@
 	<menu_item_call label="Ponerme" name="Wearable And Object Wear"/>
 	<menu label="Anexar a" name="Attach To"/>
 	<menu label="Anexar como HUD" name="Attach To HUD"/>
+	<menu_item_call label="Tocar" name="Attachment Touch" />
 	<menu_item_call label="Editar" name="Wearable Edit"/>
 	<menu_item_call label="Añadir" name="Wearable Add"/>
 	<menu_item_call label="Quitarse" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
index 4bffa689e740237a76869534c4876f56dbf235d9..cb68ad39a40a79f3ad334cfbfdc98ec7003b6878 100644
--- a/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Reemplazar" name="wear_replace"/>
 	<menu_item_call label="Ponerme" name="wear_wear"/>
 	<menu_item_call label="Añadir" name="wear_add"/>
+	<menu_item_call label="Tocar" name="touch" />
 	<menu_item_call label="Quitarme / Quitar" name="take_off_or_detach"/>
 	<menu_item_call label="Quitar" name="detach"/>
 	<context_menu label="Anexar a" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/es/menu_wearing_gear.xml b/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
index ec13f99a0161643010214dc8ab91cb6eca2d5b38..01d1b16b585a2151785c53d09d798a7af5e1018d 100644
--- a/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Editar el vestuario" name="edit"/>
+	<menu_item_call label="Tocar" name="touch"/>
+	<menu_item_call label="Editar" name="edit_item"/>
+	<menu_item_call label="Editar el vestuario" name="edit_outfit"/>
 	<menu_item_call label="Quitarme" name="takeoff"/>
 	<menu_item_call label="Copiar la lista del vestuario al portapapeles" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
index 637a14cf5b5dce97072374bc2c4b153a69f32185..54a7d9b92cf9f7bf9b7a0c9325e6707ae6fb1170 100644
--- a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Tocar" name="touch_attach"/>
 	<menu_item_call label="Quitarme" name="take_off"/>
 	<menu_item_call label="Quitar" name="detach"/>
-	<menu_item_call label="Editar el vestuario" name="edit"/>
+	<menu_item_call label="Editar el vestuario" name="edit_outfit"/>
 	<menu_item_call label="Editar" name="edit_item"/>
 	<menu_item_call label="Mostrar original" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 4d418b6eaf21cc461db02f8f1598afa7791a6a82..72d5f3752f39d0a7c9c1601af6e3ccf3bfa339cf 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -265,6 +265,10 @@ La inicialización del mercado ha fallado por un error del sistema o de la red.
 		¿Quieres revocar los derechos de modificación a los residentes seleccionados?
 		<usetemplate name="okcancelbuttons" notext="No" yestext="Sí"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		El nombre de un grupo debe contener entre [MIN_LEN] y [MAX_LEN] caracteres.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		No se ha podido crear el grupo.
 [MESSAGE]
@@ -356,7 +360,7 @@ Si no quieres que este rol siga teniendo dichas capacidades, deshabilítalas inm
 No tienes dinero suficiente para entrar.
 	</notification>
 	<notification name="CreateGroupCost">
-		Crear este grupo te costará 100 L$.
+		Crear este grupo costará L$[COST].
 Los grupos necesitan más de un miembro. Si no, son borrados permanentemente.
 Por favor, invita a miembros en las próximas 48 horas.
 		<usetemplate canceltext="Cancelar" name="okcancelbuttons" notext="Cancelar" yestext="Crear un grupo por 100 L$"/>
@@ -498,6 +502,9 @@ debes estar dentro de ella.
 	<notification name="ErrorEncodingSnapshot">
 		Error al codificar la foto.
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Necesitas L$[COST] para subir este objeto.
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Necesitas [COST] L$ para guardar una foto en el inventario. Puedes comprar L$ o bien guardar la foto en tu equipo.
 	</notification>
@@ -1745,11 +1752,14 @@ Haz clic en OK para instalar.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		El límite de grupos para las cuentas básicas es de [MAX_BASIC], y para
-las cuentas [https://secondlife.com/premium/ Premium] es de [MAX_PREMIUM].
-Si has bajado la categoría de tu cuenta, tendrás que estar por debajo del límite de [MAX_BASIC] grupos para poder apuntarte a más grupos.
-
-[https://secondlife.com/my/account/membership.php Cámbiate hoy a Premium]
+		Los residentes con membresías Básicas pueden unirse a hasta [MAX_BASIC] grupos.
+Las membresías Premium permiten hasta [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Aprende más al respecto o mejora tu membresía]
+		<usetemplate name="okbutton" yestext="Cerrar"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		Los residentes con membresías Básicas pueden unirse a hasta [MAX_BASIC] cinco grupos.
+Las membresías Premium permiten hasta [MAX_PREMIUM]. Las membresías Premium Plus permiten 
+hasta [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Aprende más al respecto o mejora tu membresía]
 		<usetemplate name="okbutton" yestext="Cerrar"/>
 	</notification>
 	<notification name="KickUser">
@@ -3307,6 +3317,22 @@ Por tu seguridad, serán bloqueadas durante unos segundos.
 		Un moderador ha silenciado tu voz.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		Desafortunadamente no fuimos capaces de obtener información sobre los beneficios para esta sesión. Esto no debería suceder en un espacio de producción normal. Por favor contacte con soporte. Esta sesión no funcionara normalmente y recomendamos reiniciar.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		Esto subirá [COUNT] objetos por un costo total de L$[COST]. ¿Deseas continuar con la subida?
+		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Subir"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		Los archivos seleccionados no pueden ser subidos en grupo.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Algunos de los archivos seleccionados no pueden ser subidos en grupo.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		Esta carga te costará [PRECIO] L$. ¿Deseas continuar?
 		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Subir"/>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 801bc86473fdac4485ca58e4779cd441e19464d2..2aaf7e89be16d095e4392c189168caed0e185bac 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -18,7 +18,7 @@
 	<string name="no_groups_msg" value="¿Buscas grupos en que participar? Prueba la [secondlife:///app/search/groups Búsqueda]."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Pulsa dos veces para abrir el mapa, pulsa mayús y arrastra para obtener una panorámica)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Pulsa dos veces para teleportarte, pulsa mayús y arrastra para obtener una panorámica)"/>
-	<string name="GroupCountWithInfo" value="Perteneces a [COUNT] grupos y puedes unirte a [REMAINING] más.  [secondlife:/// ¿Quieres más?]"/>
+	<string name="GroupCountWithInfo" value="Perteneces a [COUNT] grupos y puedes unirte a [REMAINING] más. [secondlife:/// Incrementa tu límite]"/>
 	<tab_container name="tabs">
 		<panel label="CERCANA" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@
 				<dnd_button name="minus_btn" tool_tip="Dejar el grupo seleccionado"/>
 			</panel>
 			<text name="groupcount">
-				Formas parte de [COUNT] grupos y puedes unirte a [REMAINING] más.
+				Perteneces a [COUNT] grupos y puedes unirte a [REMAINING] más.
 			</text>
 		</panel>
 		<panel label="RECIENTE" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 2b599835299a40f40614e317fb81205e5010db55..15b5713b8834586c79304595e951eaa75d885e7c 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -1646,11 +1646,14 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
 	<string name="MarketplaceUpdating">
 		actualizando...
 	</string>
+	<string name="UploadFeeInfo">
+		Las tasas se basan en tu nivel de suscripción. Niveles más altos tienen tasas más bajas. [https://secondlife.com/my/account/membership.php? Aprende más al respecto]
+	</string>
 	<string name="Open landmarks">
-		Abrir hitos
+		Abrir puntos destacados
 	</string>
 	<string name="Unconstrained">
-		Sin restricciones
+		Sin Restricciones
 	</string>
 	<string name="no_transfer" value="(no transferible)"/>
 	<string name="no_modify" value="(no modificable)"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml b/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
index a4ead48b6b3b37c6ccb7188a13a20ab284efc284..32bc564d72b6a5dfbc0e234ef6f941ee1d1c05f6 100644
--- a/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Toucher" name="touch_attach" />
+	<menu_item_call label="Modifier" name="edit_item" />
 	<menu_item_call label="Détacher" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml
index f81723e6cf5e1ca1250dcd9c4600a6d982292907..5d66d0998b5c1379de25e3e7b105916daa50b708 100644
--- a/indra/newview/skins/default/xui/fr/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="Porter" name="Wearable And Object Wear"/>
 	<menu label="Attacher à" name="Attach To"/>
 	<menu label="Attacher au HUD " name="Attach To HUD"/>
+	<menu_item_call label="Toucher" name="Attachment Touch" />
 	<menu_item_call label="Modifier" name="Wearable Edit"/>
 	<menu_item_call label="Ajouter" name="Wearable Add"/>
 	<menu_item_call label="Enlever" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
index 187cb4bcd2c996e45242d700cae939f068be0cec..a222de298ff552edf1b5ff592b7d692725d45e42 100644
--- a/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Remplacer" name="wear_replace"/>
 	<menu_item_call label="Porter" name="wear_wear"/>
 	<menu_item_call label="Ajouter" name="wear_add"/>
+	<menu_item_call label="Toucher" name="touch" />
 	<menu_item_call label="Enlever / Détacher" name="take_off_or_detach"/>
 	<menu_item_call label="Détacher" name="detach"/>
 	<context_menu label="Attacher à" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml b/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
index c3d9d908b0e840dfe23ca3456a94c7bd0a363d89..90b5ece574d3fd64a8955e849b9df9e769d4a9af 100644
--- a/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Modifier la tenue" name="edit"/>
+	<menu_item_call label="Toucher" name="touch"/>
+	<menu_item_call label="Modifier" name="edit_item"/>
+	<menu_item_call label="Modifier la tenue" name="edit_outfit"/>
 	<menu_item_call label="Enlever" name="takeoff"/>
 	<menu_item_call label="Copier la liste de la tenue dans le presse-papiers" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
index 5a7193a7cc9366a7811065065a0508e89bb7e1d8..af115b956e0ceb6d01a75e2b673c46a5b8f93e93 100644
--- a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Toucher" name="touch_attach"/>
 	<menu_item_call label="Enlever" name="take_off"/>
 	<menu_item_call label="Détacher" name="detach"/>
-	<menu_item_call label="Modifier la tenue" name="edit"/>
+	<menu_item_call label="Modifier la tenue" name="edit_outfit"/>
 	<menu_item_call label="Modifier" name="edit_item"/>
 	<menu_item_call label="Afficher l’original" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 77cfea5a6342106c622c98006c5c88c7ca462719..09905f4e5d89463db5343fdae7064a3e221ae98c 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -266,6 +266,10 @@ Souhaitez-vous accorder des droits d&apos;édition aux résidents sélectionnés
 		Souhaitez-vous retirer les droits d&apos;édition aux résidents selectionnés ?
 		<usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		Un nom de groupe doit être compris entre [MIN_LEN] et [MAX_LEN] caractères.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		Impossible de créer le groupe.
 [MESSAGE]
@@ -359,7 +363,7 @@ Souhaitez-vous continuer ?
 Vous n&apos;avez pas suffisamment de L$ pour rejoindre ce groupe.
 	</notification>
 	<notification name="CreateGroupCost">
-		La création de ce groupe coûte 100 L$.
+		La création de ce groupe coûtera L$[COST].
 Les groupes doivent comporter plus d&apos;un membre, sinon ils sont supprimés.
 Veuillez inviter des membres d&apos;ici 48 heures.
 		<usetemplate canceltext="Annuler" name="okcancelbuttons" notext="Annuler" yestext="Créer un groupe pour 100 L$"/>
@@ -500,6 +504,9 @@ Pour ne placer le média que sur une seule face, choisissez Sélectionner une fa
 	<notification name="ErrorEncodingSnapshot">
 		Erreur d&apos;encodage de la photo.
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Vous avez besoin de L$[COST] pour charger cet élément.
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Il vous faut [COST] L$ pour enregistrer une photo dans votre inventaire. Vous pouvez acheter des L$ ou enregistrer la photo sur votre ordinateur.
 	</notification>
@@ -1736,11 +1743,14 @@ Quitter le groupe ?
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		Le nombre de groupes maximum est [MAX_BASIC] pour les comptes basiques et
-[MAX_PREMIUM] pour les comptes [https://secondlife.com/premium/ premium].
-Si vous avez rétrogradé votre compte, vous devez réduire votre nombre de groupes pour passer sous le nombre de groupes maximum ([MAX_BASIC]) avant de pouvoir en rejoindre d’autres.
-
-[https://secondlife.com/my/account/membership.php Mettez à niveau dès aujourd’hui !]
+		Les résidents ayant une adhésion de base peuvent s'inscrire à [MAX_BASIC] groupes maximum.
+Les adhésions premium permettent jusqu'à [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? En savoir plus ou actualiser]
+		<usetemplate name="okbutton" yestext="Fermer"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		Les résidents ayant une adhésion de base peuvent s'inscrire à [MAX_BASIC] groupes maximum.
+Les adhésions premium permettent jusqu'à [MAX_PREMIUM]. Les adhésions à Premium Plus permettent 
+jusqu'à [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? En savoir plus ou actualiser]
 		<usetemplate name="okbutton" yestext="Fermer"/>
 	</notification>
 	<notification name="KickUser">
@@ -3307,6 +3317,22 @@ Elles vont être bloquées pendant quelques secondes pour votre sécurité.
 		Le modérateur ignore vos paroles.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		Malheureusement, nous n'avons pas pu obtenir d'informations sur les avantages pour cette session. Cela ne devrait pas se produire dans un environnement de production normal. Veuillez contacter le service d'assistance. Cette session ne fonctionnera pas normalement et nous vous recommandons de recommencer.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		Ceci permettra de charger [COUNT] éléments pour un coût total de L$[COST]. Souhaitez-vous poursuivre le téléchargement ?
+		<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Charger"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		Les fichiers sélectionnés ne peuvent pas être téléchargés en masse.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Certains des fichiers sélectionnés ne peuvent pas être téléchargés en masse.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		Ce chargement coûtera [PRICE] L$. Continuer ?
 		<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Charger"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 784708be409201f36443c1d52950ad7f8d005a23..e096b5cfe0fd4bc3b1c46d9fcbc6ffb1bd2e2814 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -18,7 +18,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
 	<string name="no_groups_msg" value="Vous souhaitez trouver des groupes à rejoindre ? Utilisez [secondlife:///app/search/groups Rechercher]."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Carte : double-clic ; Panoramique : Maj + faire glisser)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Téléportation : double-clic ; Panoramique : Maj + faire glisser)"/>
-	<string name="GroupCountWithInfo" value="Vous appartenez à [COUNT] groupes, et pouvez en rejoindre [REMAINING] autres.  [secondlife:/// Vous en voulez plus ?]"/>
+	<string name="GroupCountWithInfo" value="Vous appartenez à [COUNT] groupes et pouvez rejoindre [REMAINING] autres groupes. [secondlife:/// Augmentez votre limite]"/>
 	<tab_container name="tabs">
 		<panel label="PRÈS DE VOUS" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
 				<dnd_button name="minus_btn" tool_tip="Quitter le groupe sélectionné"/>
 			</panel>
 			<text name="groupcount">
-				Vous appartenez à [COUNT] groupes, et pouvez en rejoindre [REMAINING] autres.
+				Vous appartenez à [COUNT] groupes et pouvez rejoindre [REMAINING] autres groupes.
 			</text>
 		</panel>
 		<panel label="RÉCENT" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 1108598a462cea0bfecbf2dca3a4ca26b3887c63..6f6b74626f75213cf122ee94300f7ef27a2174b7 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1664,11 +1664,14 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life 
 	<string name="MarketplaceUpdating">
 		mise à jour...
 	</string>
+	<string name="UploadFeeInfo">
+		Les frais dépendent de votre niveau d'abonnement. Les niveaux supérieurs sont soumis à des frais moins élevés. [https://secondlife.com/my/account/membership.php? En savoir plus]
+	</string>
 	<string name="Open landmarks">
-		Ouvrir les repères
+		Points de repère ouverts
 	</string>
 	<string name="Unconstrained">
-		Sans contraintes
+		Sans contrainte
 	</string>
 	<string name="no_transfer" value=" (pas de transfert)"/>
 	<string name="no_modify" value=" (pas de modification)"/>
@@ -5130,6 +5133,15 @@ Veuillez vous reporter à http://status.secondlifegrid.net afin de déterminer s
 	<string name="Chat" value=" Chat :">
 		Chat
 	</string>
+	<string name="BaseMembership">
+		Base
+	</string>
+	<string name="PremiumMembership">
+		Premium
+	</string>
+	<string name="Premium PlusMembership">
+		Premium Plus
+	</string>
 	<string name="DeleteItems">
 		Supprimer les articles sélectionnés ?
 	</string>
diff --git a/indra/newview/skins/default/xui/it/menu_cof_attachment.xml b/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
index 699490c8f1d6f03e9b4db230ee6b258c590b5eaa..8861cc726f5c01d1d98833fa13294b61e62af77d 100644
--- a/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Tocca" name="touch_attach" />
+	<menu_item_call label="Modifica" name="edit_item" />
 	<menu_item_call label="Stacca" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml
index 84ec7c4bd4e0a9208f2de1becfd9cf46e106fac5..d2fbcafe97ef17ae0c279997026fc07455f018b5 100644
--- a/indra/newview/skins/default/xui/it/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/it/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="Indossa" name="Wearable And Object Wear"/>
 	<menu label="Attacca a" name="Attach To"/>
 	<menu label="Attacca all&apos;HUD" name="Attach To HUD"/>
+	<menu_item_call label="Tocca" name="Attachment Touch" />
 	<menu_item_call label="Modifica" name="Wearable Edit"/>
 	<menu_item_call label="Aggiungi" name="Wearable Add"/>
 	<menu_item_call label="Togli" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
index c9a02d8a86fbad0e7ddf11afe3704c9c0a49863e..23abdd7bf28c0b19020b1e0929da1907da101b60 100644
--- a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Sostituisci" name="wear_replace"/>
 	<menu_item_call label="Indossa" name="wear_wear"/>
 	<menu_item_call label="Aggiungi" name="wear_add"/>
+	<menu_item_call label="Tocca" name="touch" />
 	<menu_item_call label="Togli / Stacca" name="take_off_or_detach"/>
 	<menu_item_call label="Stacca" name="detach"/>
 	<context_menu label="Attacca a" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
index de25f88acacb309a8c6f614841a75a9219a6eff8..2f3a2aea430cffe99c088893d61abad9d7b47dd1 100644
--- a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Modifica vestiario" name="edit"/>
+	<menu_item_call label="Tocca" name="touch"/>
+	<menu_item_call label="Modifica" name="edit_item"/>
+	<menu_item_call label="Modifica vestiario" name="edit_outfit"/>
 	<menu_item_call label="Togli" name="takeoff"/>
 	<menu_item_call label="Copia gruppo vestiti negli Appunti" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
index ec375e524037f5e649fa552eb24fb2700c753ed1..08b56888a3312f255fd443b211c93f37eb4b7451 100644
--- a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Tocca" name="touch_attach"/>
 	<menu_item_call label="Togli" name="take_off"/>
 	<menu_item_call label="Stacca" name="detach"/>
-	<menu_item_call label="Modifica vestiario" name="edit"/>
+	<menu_item_call label="Modifica vestiario" name="edit_outfit"/>
 	<menu_item_call label="Modifica" name="edit_item"/>
 	<menu_item_call label="Mostra originale" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index cec35615298ef6b26ef7ac62ac826b90769b9a5a..a69fa07c500b8a536b9e97de09effc9b13e8495d 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -266,6 +266,10 @@ Vuoi concedere i diritti di modifica ai residenti selezionati?
 		Vuoi revocare i permessi di modifica dati ai residenti selezionati?
 		<usetemplate name="okcancelbuttons" notext="No" yestext="Si"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		Il nome di un gruppo deve essere compreso tra [MIN_LEN] e [MAX_LEN] caratteri.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		Non è possibile creare il gruppo.
 [MESSAGE]
@@ -360,7 +364,7 @@ Vuoi continuare?
 Non hai abbastanza L$ per iscriverti a questo gruppo.
 	</notification>
 	<notification name="CreateGroupCost">
-		La creazione di questo gruppo costerà L$ 100.
+		La creazione di questo gruppo ti costerà [COST]L$.
 I gruppi devono avere più di un partecipante, o saranno eliminati definitivamente.
 Invita altri partecipanti entro le prossime 48 ore.
 		<usetemplate canceltext="Annulla" name="okcancelbuttons" notext="Annulla" yestext="Crea un gruppo per L$ 100"/>
@@ -501,6 +505,9 @@ Per collocare il media su una sola faccia, scegli Seleziona faccia, clicca su un
 	<notification name="ErrorEncodingSnapshot">
 		Errore nella codifica della fotografia.
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Ti serviranno [COST]L$ per caricare questo articolo.
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Hai bisogno di L$ [COST] per salvare una foto nel tuo inventario. Puoi acquistare L$ o salvare la foto sul tuo computer.
 	</notification>
@@ -1740,11 +1747,14 @@ Vuoi cancellare quell&apos;elemento?
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		Il numero massimo di gruppi per gli account Basic è [MAX_BASIC] e
-per gli account [https://secondlife.com/premium/ Premium] è [MAX_PREMIUM].
-Se hai ridotto il livello del tuo account, dovrai essere iscritto a meno di [MAX_BASIC] gruppi prima di poter iscriverti a un nuovo gruppo.
-
-[https://secondlife.com/my/account/membership.php Passa a un livello superiore oggi stesso!]
+		I residenti con un'iscrizione Base possono aderire fino a [MAX_BASIC] gruppi.
+Le iscrizioni Premium consentono fino a [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Per saperne di più o per l'aggiornamento]
+		<usetemplate name="okbutton" yestext="Chiudi"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		I residenti con un'iscrizione Base possono aderire fino a [MAX_BASIC] gruppi.
+Le iscrizioni Premium consentono fino a [MAX_PREMIUM]. Le iscrizioni Premium Plus 
+consentono fino a [MAX_PREMIUM_PLUS]. [https://secondlife.com/my/account/membership.php? Per saperne di più o per l'aggiornamento]
 		<usetemplate name="okbutton" yestext="Chiudi"/>
 	</notification>
 	<notification name="KickUser">
@@ -3309,6 +3319,22 @@ Per sicurezza, verranno bloccati per alcuni secondi.
 		La tua voce è stata interrotta dal moderatore.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		Purtroppo non siamo stati in grado di ottenere informazioni utili per questa sessione. Questo non dovrebbe accadere in un normale ambiente di produzione. Si prega di contattare il supporto. Questa sessione non funzionerà correttamente, si consiglia di riavviare.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		Questo caricherà [COUNT] oggetti a un costo totale di [COST]L$. Vuoi continuare con il caricamento?
+		<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Carica"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		I file selezionati non possono essere caricati.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Alcuni dei file selezionati non possono essere caricati.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		Questo caricamento costerà L$[PRICE]. Continuare con il caricamento?
 		<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Carica"/>
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index 3174c624b4dda91fca16720e8bb5f0a55e5e519e..9eb93a26e556e1e2cc1e0b65c931f513f98c9258 100644
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -18,7 +18,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
 	<string name="no_groups_msg" value="Stai cercando gruppi di cui far parte? Prova [secondlife:///app/search/groups Cerca]."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Fai doppio clic per aprire la Mappa, premi il tasto Maiusc e trascina per la panoramica)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Fai doppio clic per teleportarti, premi il tasto Maiusc e trascina per la panoramica)"/>
-	<string name="GroupCountWithInfo" value="Fai parte di [COUNT] gruppi e puoi iscriverti a [REMAINING] altri. [secondlife:/// Ne vuoi altri?]"/>
+	<string name="GroupCountWithInfo" value="Fai parte di [COUNT] gruppi e puoi ancora unirti a [REMAINING] gruppi. [secondlife:/// Aumenta il tuo limite]"/>
 	<tab_container name="tabs">
 		<panel label="NELLE VICINANZE" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
 				<dnd_button name="minus_btn" tool_tip="Lascia il gruppo selezionato"/>
 			</panel>
 			<text name="groupcount">
-				Fai parte di [COUNT] gruppi e puoi iscriverti a [REMAINING] altri.
+				Fai parte di [COUNT] gruppi e puoi ancora unirti a [REMAINING] gruppi.
 			</text>
 		</panel>
 		<panel label="RECENTE" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 087e0610eb7e1218631df1e130faec1151737ce2..a5b3615ba0aa2691bbae14f752550b4ac7413de3 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -1654,11 +1654,14 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
 	<string name="MarketplaceUpdating">
 		in aggiornamento...
 	</string>
+	<string name="UploadFeeInfo">
+		Il costo si basa sul tuo livello di iscrizione. Più alto è il livello, più basso è il costo. [https://secondlife.com/my/account/membership.php? Scopri di più]
+	</string>
 	<string name="Open landmarks">
-		Apri luoghi di riferimento
+		Luoghi aperti
 	</string>
 	<string name="Unconstrained">
-		Libero
+		Senza limitazioni
 	</string>
 	<string name="no_transfer" value="(nessun trasferimento)"/>
 	<string name="no_modify" value="(nessuna modifica)"/>
@@ -5045,6 +5048,15 @@ Consulta la pagina http://status.secondlifegrid.net per determinare se il proble
 	<string name="Chat" value="Chat :">
 		Chat
 	</string>
+	<string name="BaseMembership">
+		Base
+	</string>
+	<string name="PremiumMembership">
+		Premium
+	</string>
+	<string name="Premium PlusMembership">
+		Premium Plus
+	</string>
 	<string name="DeleteItems">
 		Cancellare gli elementi selezionati?
 	</string>
diff --git a/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml b/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
index e786d02e40a7a7a4a3ef3fade6763d70c53e9d6c..aa07b9476edcdd48539fa33eb03eb7c41452d07a 100644
--- a/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="触る" name="touch_attach" />
+	<menu_item_call label="編集" name="edit_item" />
 	<menu_item_call label="取り外す" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml
index ec16f1cf1727ba0eb64977e12b071de87dfd7d1c..7f68c18e0b9721f0d6a7ab750c753d6c4ae1887c 100644
--- a/indra/newview/skins/default/xui/ja/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="装着" name="Wearable And Object Wear"/>
 	<menu label="装着先" name="Attach To"/>
 	<menu label="HUD 装着先" name="Attach To HUD"/>
+	<menu_item_call label="触る" name="Attachment Touch" />
 	<menu_item_call label="編集" name="Wearable Edit"/>
 	<menu_item_call label="追加" name="Wearable Add"/>
 	<menu_item_call label="取り外す" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
index c402fa0b6d2b73277162273e472d8afc7c8aa6c7..02029230ba05cbf43795532a2d3c287ea4812df9 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="交換" name="wear_replace"/>
 	<menu_item_call label="装着" name="wear_wear"/>
 	<menu_item_call label="追加" name="wear_add"/>
+	<menu_item_call label="触る" name="touch" />
 	<menu_item_call label="取り外す" name="take_off_or_detach"/>
 	<menu_item_call label="取り外す" name="detach"/>
 	<context_menu label="装着:" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
index 5334042dc9a135d821c5f7cdecb71333ddebfbf8..48aac2ed05188a0dca68769ca7862ba29c01c7c1 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="アウトフットの編集" name="edit"/>
+	<menu_item_call label="触る" name="touch"/>
+	<menu_item_call label="編集" name="edit_item"/>
+	<menu_item_call label="アウトフットの編集" name="edit_outfit"/>
 	<menu_item_call label="取り外す" name="takeoff"/>
 	<menu_item_call label="アウトフィットのリストをクリップボードにコピー" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
index bf8e72e4572615ddf7dced052d8e570194c17cac..8c331bc0086ad63f900ab8048043b9c2f24559b8 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="触る" name="touch_attach"/>
 	<menu_item_call label="取り外す" name="take_off"/>
 	<menu_item_call label="取り外す" name="detach"/>
-	<menu_item_call label="アウトフットの編集" name="edit"/>
+	<menu_item_call label="アウトフットの編集" name="edit_outfit"/>
 	<menu_item_call label="編集" name="edit_item"/>
 	<menu_item_call label="オリジナルを表示" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index bedcdbb62723f3ccfa79c765dffbdeef337d3c36..92952f4c8a34abd27cd68c910f7e648d6606cccd 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -266,6 +266,10 @@
 		選択した住人から変更権限を取り下げますか?
 		<usetemplate name="okcancelbuttons" notext="いいえ" yestext="はい"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		グループ名は [MIN_LEN] ~ [MAX_LEN] 文字である必要があります。
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		グループを作成できません。
 [MESSAGE]
@@ -367,7 +371,7 @@
 L$ が不足しているのでこのグループに参加することができません。
 	</notification>
 	<notification name="CreateGroupCost">
-		このグループを作るには L$ 100 かかります。
+		このグループ作成にかかる費用:L$[COST]
 一人ではグループにならないので、永久に削除されてしまいます。
 48 時間以内にメンバーを勧誘し、入会してもらってください。
 		<usetemplate canceltext="キャンセル" name="okcancelbuttons" notext="キャンセル" yestext="L$100 でグループを作成"/>
@@ -518,6 +522,9 @@ L$ が不足しているのでこのグループに参加することができ
 	<notification name="ErrorEncodingSnapshot">
 		スナップショットのエンコード化でエラーが出ました!
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		このアイテムをアップロードするためには L$[COST] が必要です。
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		インベントリに写真を保存するには L$[COST] が必要です。L$ を購入するか、代わりに写真をっコンピュータに保存できます。
 	</notification>
@@ -1773,11 +1780,14 @@ https://secondlife.com/support/downloads/ からダウンロードしてくだ
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		ベースアカウントのグループ制限は [MAX_BASIC]、[https://secondlife.com/premium/ プレミアム] アカウントの
-グループ制限は [MAX_PREMIUM] です。
-アカウントをダウングレードした場合、さらにグループに参加する前に、下の [MAX_BASIC] グループ制限を取得する必要があります。
-
-[https://secondlife.com/my/account/membership.php 今すぐアップグレード!]
+		ベーシック会員の住民は、最大 [MAX_BASIC] グループまで参加することができます。
+プレミアム会員は、最大 [MAX_PREMIUM] まで可能です。[https://secondlife.com/my/account/membership.php? 詳細、またはアップグレード]
+		<usetemplate name="okbutton" yestext="閉じる"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		ベーシック会員の住民は、最大 [MAX_BASIC] グループまで参加することができます。
+プレミアム会員は、最大 [MAX_PREMIUM] まで可能です。プレミアムプラス会員は、最大 [MAX_PREMIUM_PLUS] まで可能です。
+[https://secondlife.com/my/account/membership.php? 詳細、またはアップグレード]
 		<usetemplate name="okbutton" yestext="閉じる"/>
 	</notification>
 	<notification name="KickUser">
@@ -3352,6 +3362,22 @@ M キーを押して変更します。
 		モデレーターがあなたのボイスをミュートしました。
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		残念ながら、このセッションのベネフィット情報を得ることができませんでした。通常のプロダクション環境で起こることではありません。サポートまでご連絡ください。このセッションは通常通りに作動しませんので、再スタートをお薦めします
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		合計 L$[COST] で [COUNT] アイテムがアップロードされます。 アップロードを続けますか?
+		<usetemplate name="okcancelbuttons" notext="取り消し" yestext="アップロード"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		選択したファイルは、まとめてアップロードできません。
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		選択したファイルのいくつかは、まとめてアップロードできません。
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		このアップロードは L$[PRICE] のコストがかかります。アップロードを続けますか?
 		<usetemplate name="okcancelbuttons" notext="取り消し" yestext="アップロード"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 656a8e2ade7afb22b6e218d54cf3c9c4c16ad615..be00a3c122aef7756a715cee619951349ad941e9 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -18,7 +18,7 @@
 	<string name="no_groups_msg" value="グループをお探しですか? [secondlife:///app/search/groups 検索] をお試しください。"/>
 	<string name="MiniMapToolTipMsg" value="[地域](ダブルクリックで地図を開く。Shift‐ドラッグで水平・垂直移動)"/>
 	<string name="AltMiniMapToolTipMsg" value="[地域](ダブルクリックでテレポート。Shift‐ドラッグで水平・垂直移動)"/>
-	<string name="GroupCountWithInfo" value="あなたは [COUNT] グループに属しているので、まだ [REMAINING] 参加できます。[secondlife:/// 詳細]"/>
+	<string name="GroupCountWithInfo" value="あなたは現在、[COUNT] グループに属しています。あと [REMAINING] グループに参加することができます。[secondlife:/// 上限を増やす]"/>
 	<tab_container name="tabs">
 		<panel label="近く" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@
 				<dnd_button name="minus_btn" tool_tip="選択したグループから脱退"/>
 			</panel>
 			<text name="groupcount">
-				あなたは[COUNT]グループに属しているので、まだ[REMAINING]参加できます。
+				あなたは現在、[COUNT] グループに属しています。あと [REMAINING] グループに参加することができます。
 			</text>
 		</panel>
 		<panel label="最新" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index f6c4a8d13f35bfb2e67a3a397551a34c26c3404e..10a2e811199c4c4285d6a6b59c57b61c6bf05ad5 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -1662,11 +1662,14 @@ support@secondlife.com にお問い合わせください。
 	<string name="MarketplaceUpdating">
 		アップデート中...
 	</string>
+	<string name="UploadFeeInfo">
+		料金はサブスクリプションのレベルにより異なります。レベルが高いほど、料金が下がります。[https://secondlife.com/my/account/membership.php? 詳細]
+	</string>
 	<string name="Open landmarks">
-		ランドマークを開く
+		オープン ランドマーク
 	</string>
 	<string name="Unconstrained">
-		非拘束
+		アンコンストレインド(制約なし)
 	</string>
 	<string name="no_transfer" value=" (再販・プレゼント不可)"/>
 	<string name="no_modify" value=" (編集不可)"/>
@@ -5128,6 +5131,15 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
 	<string name="Chat" value=" チャット:">
 		チャット
 	</string>
+	<string name="BaseMembership">
+		ベース
+	</string>
+	<string name="PremiumMembership">
+		プレミアム
+	</string>
+	<string name="Premium PlusMembership">
+		プレミアムプラス
+	</string>
 	<string name="DeleteItems">
 		選択したアイテムを削除しますか
 	</string>
diff --git a/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml b/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
index add2d59998fe703a1d4504b7a8bc3d37d91967ab..f5fbf5c0c14a554c11ea4d20855f5add15ac7d04 100644
--- a/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Dotknij" name="touch_attach" />
+	<menu_item_call label="Edytuj" name="edit_item" />
 	<menu_item_call label="Odłącz" name="detach" />
 </context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_inventory.xml b/indra/newview/skins/default/xui/pl/menu_inventory.xml
index 0edb680b163f0ecd4f2c71d1cdf8b2ba5daa0e3c..1aeffc58b749eea239ca176d9602febd5bcd4d8d 100644
--- a/indra/newview/skins/default/xui/pl/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inventory.xml
@@ -85,6 +85,7 @@
 	<menu_item_call label="Załóż" name="Wearable And Object Wear" />
 	<menu label="Dołącz do" name="Attach To" />
 	<menu label="Dołącz do HUD-a" name="Attach To HUD" />
+	<menu_item_call label="Dotknij" name="Attachment Touch" />
 	<menu_item_call label="Edytuj" name="Wearable Edit" />
 	<menu_item_call label="Dodaj/dołącz" name="Wearable Add" />
 	<menu_item_call label="Zdejmij" name="Take Off" />
diff --git a/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
index 260b86cb073373ffd9bc62e4ced1be5187a92816..b0ef8e4393324e7d2f860c1ec93e5a4fdea9d2e4 100644
--- a/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="ZastÄ…p" name="wear_replace" />
 	<menu_item_call label="Załóż" name="wear_wear" />
 	<menu_item_call label="Dodaj" name="wear_add" />
+	<menu_item_call label="Dotknij" name="touch" />
 	<menu_item_call label="Zdejmij/Odłącz" name="take_off_or_detach" />
 	<menu_item_call label="Odłącz" name="detach" />
 	<context_menu label="Dołącz do" name="wearable_attach_to" />
diff --git a/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml b/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
index 73138b2cf752f1241db0fb76e16535e04c40af40..c129448adc5a166e60ac45448ea2c3841dc33e67 100644
--- a/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Edytuj strój" name="edit" />
+	<menu_item_call label="Dotknij" name="touch"/>
+	<menu_item_call label="Edytuj" name="edit_item"/>
+	<menu_item_call label="Edytuj strój" name="edit_outfit" />
 	<menu_item_call label="Zdejmij" name="takeoff" />
 	<menu_item_call label="Kopiuj listę przedmiotów stroju do schowka" name="copy" />
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
index 09c82da4273b33de0934b8b4b3a68e1507936585..188f77a3bb7f643371af530114751f09a8cc823f 100644
--- a/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu name="Wearing">
+	<menu_item_call label="Dotknij" name="touch_attach"/>
+	<menu_item_call label="Edytuj" name="edit_item"/>
 	<menu_item_call label="Zdejmij" name="take_off" />
 	<menu_item_call label="Odłącz" name="detach" />
-	<menu_item_call label="Edytuj strój" name="edit" />
+	<menu_item_call label="Edytuj strój" name="edit_outfit" />
 </context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml b/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
index 527e3af3c937ac7a4ac365108036b35ecf5ff638..5072b54f0689aa97255091efcaeb914706015ad8 100644
--- a/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Tocar" name="touch_attach" />
+	<menu_item_call label="Editar" name="edit_item" />
 	<menu_item_call label="Separar" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml
index 78a0482deea2b07fc6b6726f3a14e0ef1f952d6e..363ed4398650f47121a10839561c39c3ead4242d 100644
--- a/indra/newview/skins/default/xui/pt/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="Vestir" name="Wearable And Object Wear"/>
 	<menu label="Anexar a" name="Attach To"/>
 	<menu label="Anexar ao HUD" name="Attach To HUD"/>
+	<menu_item_call label="Tocar" name="Attachment Touch" />
 	<menu_item_call label="Editar" name="Wearable Edit"/>
 	<menu_item_call label="Adicionar" name="Wearable Add"/>
 	<menu_item_call label="Tirar" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
index 2487f6779f6306dd610254cce7bb65b0102cb608..2d16736277fc195b41582dc7d4abfba6b0eb4805 100644
--- a/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Trocar" name="wear_replace"/>
 	<menu_item_call label="Vestir" name="wear_wear"/>
 	<menu_item_call label="Adicionar" name="wear_add"/>
+	<menu_item_call label="Tocar" name="touch" />
 	<menu_item_call label="Tirar / Separar" name="take_off_or_detach"/>
 	<menu_item_call label="Separar" name="detach"/>
 	<context_menu label="Colocar em" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml b/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
index 75dca703cb0c39cee995c71fd1cbb6fc68141924..bc24ffcdd969b16998508e5fac317eddc8eb5299 100644
--- a/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Editar look" name="edit"/>
+	<menu_item_call label="Tocar" name="touch"/>
+	<menu_item_call label="Editar" name="edit_item"/>
+	<menu_item_call label="Editar look" name="edit_outfit"/>
 	<menu_item_call label="Tirar" name="takeoff"/>
 	<menu_item_call label="Copiar lista do look para a área de transferência" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
index 42aa3862154d692ebc0e1d2b0b2424aa30a4ed7d..d00fd9ae28379b507d1ff9985d9e82f0ec42caa0 100644
--- a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Tocar" name="touch_attach"/>
 	<menu_item_call label="Tirar" name="take_off"/>
 	<menu_item_call label="Tirar" name="detach"/>
-	<menu_item_call label="Editar look" name="edit"/>
+	<menu_item_call label="Editar look" name="edit_outfit"/>
 	<menu_item_call label="Editar" name="edit_item"/>
 	<menu_item_call label="Mostrar original" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 2a93ff4f63b28bed88245791cb1f760fa2bae9c2..733ec2c70993faf78ea3909d252286643b70a080 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -265,6 +265,10 @@ Deseja conceder direitos de modificação para os residentes selecionados?
 		Você quer revogar os direitos de edição para os residentes selecionados?
 		<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		O nome do grupo deve conter entre [MIN_LEN] e [MAX_LEN] caracteres.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		Não foi possível criar um grupo.
 [MESSAGE]
@@ -359,7 +363,7 @@ Deseja continuar?
 Você não tem L$ suficientes para associar-se a este grupo.
 	</notification>
 	<notification name="CreateGroupCost">
-		Criar este grupo custa L$100.
+		Criar este grupo custará L$[COST].
 Grupos ser formados por mais de um membro, caso contrário serão definitivamente excluídos. 
 Convite outros membros dentro de 48 horas.
 		<usetemplate canceltext="Cancelar" name="okcancelbuttons" notext="Cancelar" yestext="Criar grupo por L$100"/>
@@ -498,6 +502,9 @@ Para colocar a mídia em só uma face, selecione Selecionar face e clique na fac
 	<notification name="ErrorEncodingSnapshot">
 		Erro ao codificar a foto.
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Você precisa de L$[COST] para fazer o upload deste item.
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Você precisa de L$ [COST] para salvar uma foto em seu inventário. Você pode comprar L$ ou salvar a foto em seu computador.
 	</notification>
@@ -1729,12 +1736,15 @@ Deseja prosseguir?
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		O limite de grupos para as contas básicas é [MAX_BASIC] e para as contas [https://secondlife.com/premium/ premium],
-é [MAX_PREMIUM].
-Se você fizer downgrade de sua conta, precisará ficar abaixo do limite de grupos [MAX_BASIC] antes de entrar em mais.
-
-[https://secondlife.com/my/account/membership.php Faça o upgrade hoje!]
+		Residentes com o plano Básico podem participar de até [MAX_BASIC] grupos.
+O plano Premium permite até [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Saiba mais ou faça um upgrade]
 		<usetemplate name="okbutton" yestext="Fechar"/>
+	</notification>
+		<notification name="GroupLimitInfoPlus">
+			Residentes com o plano Básico podem participar de até [MAX_BASIC] grupos.
+O plano Premium permite até [MAX_PREMIUM]. O plano Premium Plus permite até [MAX_PREMIUM_PLUS]. 
+[https://secondlife.com/my/account/membership.php? Saiba mais ou faça um upgrade]
+			<usetemplate name="okbutton" yestext="Fechar"/>
 	</notification>
 	<notification name="KickUser">
 		Chutar este residente com qual mensagem?
@@ -3295,6 +3305,22 @@ Para sua segurança, os SLurls serão bloqueados por alguns instantes.
 		Sua voz foi silenciada pelo moderador.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		Infelizmente, não conseguimos obter as informações de benefícios para esta sessão. Isto não deveria ocorrer em um ambiente de produção normal. Por favor, contate o suporte. Esta sessão não funcionará normalmente e recomendamos que você reinicie.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		Será feito o upload de [COUNT] itens, com um custo total de L$[COST]. Você deseja prosseguir com o upload?
+		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Carregar"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		Não é possível fazer o upload dos arquivos selecionados de uma vez só.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Não é possível fazer o upload de alguns dos arquivos selecionados de uma vez só.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		O carregamento custa L$[PRICE]. Deseja prosseguir?
 		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Carregar"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index 930279f7c8761145c6d19e24a26ec7b0a3e304cc..ce50449b03a92b2892d3f480f23afe2ab12992c5 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -18,7 +18,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
 	<string name="no_groups_msg" value="À procura de grupos interessantes? Tente fazer uma [secondlife:///app/search/groups Busca]."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Clique duas vezes para abrir o mapa, shift+arraste para a visão pan)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Clique duas vezes para teletransportar, shift+arraste para a visão pan)"/>
-	<string name="GroupCountWithInfo" value="Você pertence a [COUNT] grupos e pode entrar em mais [REMAINING].  [secondlife:/// Quer mais?]"/>
+	<string name="GroupCountWithInfo" value="Você faz parte de [COUNT] grupos e pode participar de mais [REMAINING]. [secondlife:/// Aumente o seu limite]"/>
 	<tab_container name="tabs">
 		<panel label="PROXIMIDADE" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
 				<dnd_button name="minus_btn" tool_tip="Sair do grupo selecionado"/>
 			</panel>
 			<text name="groupcount">
-				Você pertence a [COUNT] grupos e pode entrar em mais [REMAINING].
+				Você faz parte de [COUNT] grupos e pode participar de mais [REMAINING].
 			</text>
 		</panel>
 		<panel label="RECENTE" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index ee2e8dfda8eb1602cc8fee2ea63684b5420fc0ca..20cad7c3bbdde23294243dc81da337dba7513cef 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -1614,11 +1614,14 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
 	<string name="MarketplaceUpdating">
 		atualizando...
 	</string>
+	<string name="UploadFeeInfo">
+		A taxa é baseada em seu nível de inscrição. Níveis mais altos possuem taxas mais baixas. [https://secondlife.com/my/account/membership.php? Saiba mais]
+	</string>
 	<string name="Open landmarks">
-		Marcos abertos
+		Marcos em aberto
 	</string>
 	<string name="Unconstrained">
-		Sem limites
+		Ilimitado
 	</string>
 	<string name="no_transfer" value="(não transferível)"/>
 	<string name="no_modify" value="(não modificável)"/>
@@ -5004,6 +5007,9 @@ Visite http://status.secondlifegrid.net para saber se foi detectado um problema
 	<string name="Chat" value="Bate papo">
 		Bate-papo
 	</string>
+	<string name="BaseMembership">
+		Básico
+	</string>
 	<string name="DeleteItems">
 		Excluir itens selecionados?
 	</string>
diff --git a/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml b/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
index 72d1bc52b539f2e4c0d299ecd605f5da5c0797f5..bc60188e2d16259118f2fb0d9e48a35ea5a00d87 100644
--- a/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Коснуться" name="touch_attach" />
+	<menu_item_call label="Изменить" name="edit_item" />
 	<menu_item_call label="Отсоединить" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml
index 05cccebafc79ad172b0c0511fbaba82744945824..0f63324e904ac24e9b60b869b4d7ebac444d1d89 100644
--- a/indra/newview/skins/default/xui/ru/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="Надеть" name="Wearable And Object Wear"/>
 	<menu label="Присоединить к" name="Attach To"/>
 	<menu label="Присоединить к данным в игре" name="Attach To HUD"/>
+	<menu_item_call label="Коснуться" name="Attachment Touch" />
 	<menu_item_call label="Изменить" name="Wearable Edit"/>
 	<menu_item_call label="Добавить" name="Wearable Add"/>
 	<menu_item_call label="Снять" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
index 2832e17b7d0f77e6e67ce97e73ffb9987be92b19..caef7db4581c9ac4a3c7c2b0c833ca6801bdecde 100644
--- a/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="Заменить" name="wear_replace"/>
 	<menu_item_call label="Надеть" name="wear_wear"/>
 	<menu_item_call label="Добавить" name="wear_add"/>
+	<menu_item_call label="Коснуться" name="touch" />
 	<menu_item_call label="Снять / отсоединить" name="take_off_or_detach"/>
 	<menu_item_call label="Отсоединить" name="detach"/>
 	<context_menu label="Присоединить" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
index c2351fbfff7a04f00755393e7b523834de8047ed..01491b969432226df90280043b59d3ac7848eefe 100644
--- a/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Изменить костюм" name="edit"/>
+	<menu_item_call label="Коснуться" name="touch"/>
+	<menu_item_call label="Изменить" name="edit_item"/>
+	<menu_item_call label="Изменить костюм" name="edit_outfit"/>
 	<menu_item_call label="Снять" name="takeoff"/>
 	<menu_item_call label="Копировать список костюмов в буфер обмена" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
index 1e32090c2afe5a2e31ad88184cebf8bf1cb92f6b..e68b67bb3330663840cd3dddf29284b8364eac9e 100644
--- a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Коснуться" name="touch_attach"/>
 	<menu_item_call label="Снять" name="take_off"/>
 	<menu_item_call label="Отсоединить" name="detach"/>
-	<menu_item_call label="Изменить костюм" name="edit"/>
+	<menu_item_call label="Изменить костюм" name="edit_outfit"/>
 	<menu_item_call label="Изменить" name="edit_item"/>
 	<menu_item_call label="Показать оригинал" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index 1200278f1e348ca9f82e916285cccb0979d57b3d..e75fd1fd822cfe5746160d1afe1413e0bb30f3a0 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -266,6 +266,10 @@
 		Отобрать у выбранных жителей права на изменение?
 		<usetemplate name="okcancelbuttons" notext="Нет" yestext="Да"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		Название группы может содержать от [MIN_LEN] до [MAX_LEN] символов.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		Невозможно создать группу.
 [MESSAGE]
@@ -360,7 +364,7 @@
 У вас не хватает L$ для вступления.
 	</notification>
 	<notification name="CreateGroupCost">
-		Создание этой группы стоит L$100.
+		Создание этой группы стоит L$[COST].
 В группе должно быть более одного участника, иначе она будет удалена.
 Пригласите участников в ближайшие 48 часов.
 		<usetemplate canceltext="Отмена" name="okcancelbuttons" notext="Отмена" yestext="Создать группу за L$100"/>
@@ -500,6 +504,9 @@
 	<notification name="ErrorEncodingSnapshot">
 		Ошибка при кодировке снимка.
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Чтобы загрузить этот предмет, вам нужно L$[COST].
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Требуется L$[COST] для сохранения фото в вашем инвентаре. Купите L$ или сохраните фото на компьютере.
 	</notification>
@@ -1738,11 +1745,14 @@
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		Максимальное число групп для пользователя базового аккаунта составляет [MAX_BASIC],
-а для [https://secondlife.com/premium/ премиум]-аккаунта – [MAX_PREMIUM].
-Чтобы вступать в новые группы после возврата к базовому аккаунту, вам придется выйти из части групп, чтобы их общее число было меньше [MAX_BASIC].
-
-[https://secondlife.com/my/account/membership.php Перейдите на премиум-членство!]
+		Резиденты с Базовым аккаунтом могут присоединиться к [MAX_BASIC] группам.
+Премиум аккаунт разрешает до [MAX_PREMIUM]. [https://secondlife.com/my/account/membership.php? Узнайте больше или расширьте свой аккаунт]
+		<usetemplate name="okbutton" yestext="Закрыть"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		Резиденты с Базовым аккаунтом могут присоединиться к [MAX_BASIC] группам.
+Премиум аккаунт разрешает до [MAX_PREMIUM]. Премиум Плюс аккаунт разрешает до [MAX_PREMIUM_PLUS]. 
+[https://secondlife.com/my/account/membership.php? Узнайте больше или расширьте свой аккаунт]
 		<usetemplate name="okbutton" yestext="Закрыть"/>
 	</notification>
 	<notification name="KickUser">
@@ -3306,6 +3316,22 @@
 		Ваш голос заглушен модератором.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		К сожалению, в этой сессии мы не смогли получить информацию о преимуществах аккаунта. Такое не должно происходить в нормально работающей среде. Пожалуйста, свяжитесь со службой поддержки. Эта сессия работает некорректно, поэтому мы рекомендуем вам перезапустить программу.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+		<notification name="BulkUploadCostConfirmation">
+		Этим действием загружается [COUNT] предметов на общую стоимость L$[COST]. Вы хотите продолжить загрузку?
+		<usetemplate name="okcancelbuttons" notext="Отмена" yestext="Загрузить"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		Выбранные файлы не могут быть загружены группой.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Некоторые из выбранных файлов не могут быть загружены группой.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		Эта передача будет стоить L$[PRICE]. Продолжить передачу?
 		<usetemplate name="okcancelbuttons" notext="Отмена" yestext="Передать"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 05b7997e5d073905ea56e1b5819c38b964f295f2..8170c8d26f86c42fd62796182bacd91e3db93c16 100644
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -18,7 +18,7 @@
 	<string name="no_groups_msg" value="Ищете группу, чтобы присоединиться к ней? Воспользуйтесь [secondlife:///app/search/groups поиском]."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Двойной щелчок открывает карту, shift+перетягивание – обзор)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Двойной щелчок – телепортация, shift+перетягивание – обзор)"/>
-	<string name="GroupCountWithInfo" value="Вы входите в [COUNT] групп и можете присоединиться еще к [REMAINING].  [secondlife:/// Хотите еще?]"/>
+	<string name="GroupCountWithInfo" value="Вы состоите в [COUNT] группах, и можете присоединиться еще к [REMAINING]. [secondlife:/// Расширить свои лимиты]"/>
 	<tab_container name="tabs">
 		<panel label="РЯДОМ" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@
 				<dnd_button name="minus_btn" tool_tip="Покинуть выбранную группу"/>
 			</panel>
 			<text name="groupcount">
-				Вы входите в [COUNT] групп и можете присоединиться еще к [REMAINING].
+				Вы состоите в [COUNT] группах, и можете присоединиться еще к [REMAINING].
 			</text>
 		</panel>
 		<panel label="НЕДАВНИЕ" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 02560af6056f80648fc790e2eef52b06852b2d4b..98cf52f2d2bf8d23700c472a50f2814eee0ca730 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -1661,11 +1661,14 @@ support@secondlife.com.
 	<string name="MarketplaceUpdating">
 		обновление...
 	</string>
+	<string name="UploadFeeInfo">
+		Тариф зависит от типа вашей подписки. Тарифы для владельцев расширенных пакетов меньше. [https://secondlife.com/my/account/membership.php? Узнать больше]
+	</string>
 	<string name="Open landmarks">
-		Открыть закладки
+		Открыть сохраненные локации	
 	</string>
 	<string name="Unconstrained">
-		Без ограничения
+		Без ограничений
 	</string>
 	<string name="no_transfer" value="(не передается)"/>
 	<string name="no_modify" value="(не изменяется)"/>
@@ -5124,6 +5127,15 @@ support@secondlife.com.
 	<string name="Chat">
 		Чат
 	</string>
+	<string name="BaseMembership">
+		Базовый
+	</string>
+	<string name="PremiumMembership">
+		Премиум
+	</string>
+	<string name="Premium PlusMembership">
+		Премиум Плюс
+	</string>
 	<string name="DeleteItems">
 		Удалить выбранные объекты?
 	</string>
diff --git a/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml b/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
index d57c43f6c1b0fc39e7abbbe0a78b1f77ba464df6..82c9b286bb926b43898c8cea635dcaff72b99f2d 100644
--- a/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="Dokun" name="touch_attach" />
+	<menu_item_call label="Düzenle" name="edit_item" />
 	<menu_item_call label="Ayır" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_inventory.xml b/indra/newview/skins/default/xui/tr/menu_inventory.xml
index d5e4113febf98309926870d7f80dc2467f84000d..ce85c437cb564ef759a20dcce688c0ddbe0dc211 100644
--- a/indra/newview/skins/default/xui/tr/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="Giy" name="Wearable And Object Wear"/>
 	<menu label="Åžuna Ekle:" name="Attach To"/>
 	<menu label="BÃœG&apos;e Ekle" name="Attach To HUD"/>
+	<menu_item_call label="Dokun" name="Attachment Touch" />
 	<menu_item_call label="Düzenle" name="Wearable Edit"/>
 	<menu_item_call label="Ekle" name="Wearable Add"/>
 	<menu_item_call label="Çıkar" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
index 448202df873edd8047f570b85da2a1bb64f4cc8b..486f76a29af6968b40494789ad51cc53e55f69ed 100644
--- a/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="DeÄŸiÅŸtir" name="wear_replace"/>
 	<menu_item_call label="Giy" name="wear_wear"/>
 	<menu_item_call label="Ekle" name="wear_add"/>
+	<menu_item_call label="Dokun" name="touch" />
 	<menu_item_call label="Çıkar / Ayır" name="take_off_or_detach"/>
 	<menu_item_call label="Ayır" name="detach"/>
 	<context_menu label="Åžuna ekle" name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml b/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
index 438e580cd3d5e8a382ec3947ffc6257fe9952db3..1594cf3afbed6d5693785710244c908c0b7f0f67 100644
--- a/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="Dış Görünümü Düzenle" name="edit"/>
+	<menu_item_call label="Dokun" name="touch"/>
+	<menu_item_call label="Düzenle" name="edit_item"/>
+	<menu_item_call label="Dış Görünümü Düzenle" name="edit_outfit"/>
 	<menu_item_call label="Çıkar" name="takeoff"/>
 	<menu_item_call label="Dış görünüm listesini panoya kopyala" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
index 1db95c17e1fdc3698611db8e6e0fcea6046bc4a4..56397c8628740fd8f656d21b2e168eb0ecac77f6 100644
--- a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="Dokun" name="touch_attach"/>
 	<menu_item_call label="Çıkar" name="take_off"/>
 	<menu_item_call label="Ayır" name="detach"/>
-	<menu_item_call label="Dış Görünümü Düzenle" name="edit"/>
+	<menu_item_call label="Dış Görünümü Düzenle" name="edit_outfit"/>
 	<menu_item_call label="Düzenle" name="edit_item"/>
 	<menu_item_call label="Orijinali Göster" name="show_original"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 087619f2b6e608fe1e34645417ed64713d2cf38c..17d2969d196d12e4880271f5dde4bfb66a6b1c81 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -266,6 +266,10 @@ Seçili Sakinlere değişiklik yapma hakkı vermek istiyor musunuz?
 		Seçili Sakinlerin değişiklik yapma hakkını iptal etmek istiyor musunuz?
 		<usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/>
 	</notification>
+	<notification name="GroupNameLengthWarning">
+		Bir grup adı [MIN_LEN] ile [MAX_LEN] karakter olmalıdır.
+		<usetemplate name="okbutton" yestext="Tamam"/>
+	</notification>
 	<notification name="UnableToCreateGroup">
 		Grup oluşturulamıyor.
 [MESSAGE]
@@ -360,7 +364,7 @@ Devam etmek istiyor musunuz?
 Bu gruba katılmak için yeterli L$&apos;na sahip değilsiniz.
 	</notification>
 	<notification name="CreateGroupCost">
-		Bu grubu oluşturmanın maliyeti: L$ 100.
+		Bu grubu oluşturmak L$[COST]'dır.
 Grupların birden fazla üyeye sahip olması gereklidir, aksi takdirde grup kalıcı olarak silinir.
 Lütfen 48 saat içinde diğer üyeleri davet edin.
 		<usetemplate canceltext="İptal" name="okcancelbuttons" notext="İptal" yestext="L$ 100 ödeyerek grubu oluştur"/>
@@ -501,6 +505,9 @@ Ortamı sadece bir yüze yerleştirmek için, Yüz Seç&apos;i seçin ve ardınd
 	<notification name="ErrorEncodingSnapshot">
 		Anlık görüntü kodlanırken hata oluştu.
 	</notification>
+	<notification name="ErrorCannotAffordUpload">
+		Bu nesneyi yüklemek için L$[COST] ' a ihtiyacınız var.
+	</notification>
 	<notification name="ErrorPhotoCannotAfford">
 		Envanterinize bir fotoğraf kaydedebilmek için [COST] L$ paraya ihtiyacınız var. L$ satın alabilir veya bunun yerine fotoğrafı bilgisayarınıza kaydedebilirsiniz.
 	</notification>
@@ -1739,11 +1746,14 @@ Gruptan ayrılmak istiyor musunuz?
 		<usetemplate name="okbutton" yestext="Tamam"/>
 	</notification>
 	<notification name="GroupLimitInfo">
-		Temel hesaplar için grup limiti [MAX_BASIC], [https://secondlife.com/premium/ özel] hesaplar 
-içinse [MAX_PREMIUM] olarak belirlenmiştir.
-Hesabınızı indirgediyseniz, daha fazla gruba katılmak için önce grup sayınızı [MAX_BASIC] grubun altına düşürmelisiniz.
-
-[https://secondlife.com/my/account/membership.php Şimdi yükselt!]
+		Temel üyelikler [MAX_BASIC]'a kadar katılım sağlayabilir.
+Premium üyelikler [MAX_PREMIUM] 'a kadar izinlidir. [https://secondlife.com/my/account/membership.php? Daha fazla bilgi alın ya da üyeiliğinizi yükseltin]
+		<usetemplate name="okbutton" yestext="Kapat"/>
+	</notification>
+	<notification name="GroupLimitInfoPlus">
+		Temel üyelik sahibi yerleşimciler [MAX_BASIC]'a kadar olan gruplara katılabilir.
+Premium üyeler [MAX_PREMIUM] 'a kadar izinlidir. Premium Plus üyeler [MAX_PREMIUM_PLUS] 'a kadar izinlidir. 
+[https://secondlife.com/my/account/membership.php? Daha fazla bilgi alın ya da üyeiliğinizi yükseltin]
 		<usetemplate name="okbutton" yestext="Kapat"/>
 	</notification>
 	<notification name="KickUser">
@@ -3306,6 +3316,22 @@ Güvenliğiniz için birkaç saniye engellenecek.
 		Sesli sohbetiniz moderatör tarafından engellendi.
 		<usetemplate name="okbutton" yestext="Tamam"/>
 	</notification>
+	<notification name="FailedToGetBenefits">
+		Maalesef, bu oturumun avantajlarıyla ilgili bilgilere ulaşamıyoruz. Normal prodüksiyon ortamında yaşanmaması gereken bir durumdur. Lütfen destek ekibiyle iletişime geçin. Bu oturum normal bir şekilde çalışmayacaktır, yeniden başlatmanızı öneririz.
+		<usetemplate name="okbutton" yestext="Tamam"/>
+	</notification>
+	<notification name="BulkUploadCostConfirmation">
+		Bu, toplam tutarı L$[COST] olan [COUNT] nesne yükleyecektir. Bu yüklemeye devam etmek istiyor musunuz?
+		<usetemplate name="okcancelbuttons" notext="İptal" yestext="Karşıya Yükle"/>
+	</notification>
+	<notification name="BulkUploadNoCompatibleFiles">
+		Seçili dosyalar aynı anda yüklenemez.
+		<usetemplate name="okbutton" yestext="Tamam"/>
+	</notification>
+	<notification name="BulkUploadIncompatibleFiles">
+		Seçili bazı dosyalar aynı anda yüklenemez.
+		<usetemplate name="okbutton" yestext="Tamam"/>
+	</notification>
 	<notification name="UploadCostConfirmation">
 		Bu karşıya yükleme işleminin maliyeti L$[PRICE] olacak, karşıya yüklemeye devam etmek istiyor musunuz?
 		<usetemplate name="okcancelbuttons" notext="İptal" yestext="Karşıya Yükle"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 6c06bbb5d73b28b0d4e9d577ffed94e8c8417e2b..acbcd2a544b2a66fd9ff4a7aa5a1feb1798e7331 100644
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -18,7 +18,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
 	<string name="no_groups_msg" value="Katılacak Gruplar mı arıyorsunuz? [secondlife:///app/search/groups Ara] deneyin."/>
 	<string name="MiniMapToolTipMsg" value="[REGION](Haritayı açmak için çift tıkla, yatay hareket için shift çek)"/>
 	<string name="AltMiniMapToolTipMsg" value="[REGION](Işınlamak için çift tıkla, yatay hareket için shift çek)"/>
-	<string name="GroupCountWithInfo" value="[COUNT] gruba üyesiniz, daha [REMAINING] gruba üye olabilirsiniz.  [secondlife:/// Daha fazlasını mı istiyorsunuz?]"/>
+	<string name="GroupCountWithInfo" value="[COUNT] gruba üyesin ve [REMAINING] daha gruba üye olabilirsin. [secondlife:/// Limitini arttır]"/>
 	<tab_container name="tabs">
 		<panel label="YAKIN" name="nearby_panel">
 			<panel label="bottom_panel" name="nearby_buttons_panel">
@@ -52,7 +52,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
 				<dnd_button name="minus_btn" tool_tip="Seçilen gruptan ayrıl"/>
 			</panel>
 			<text name="groupcount">
-				[COUNT] gruba üyesiniz, daha [REMAINING] gruba üye olabilirsiniz.
+				[COUNT] gruba üyesin ve [REMAINING] daha gruba üye olabilirsin.
 			</text>
 		</panel>
 		<panel label="SON" name="recent_panel">
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index d52560695a317ec345b8cb43b41f3706ff11dcae..3f1a964e4f2f22a5fc768875929d99c4108b467a 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -1661,11 +1661,14 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
 	<string name="MarketplaceUpdating">
 		güncelleniyor...
 	</string>
+	<string name="UploadFeeInfo">
+		Ücret, üyelik seviyene göre belirlenir. Yüksek seviyelere daha düşük ücretler uygulanır. [https://secondlife.com/my/account/membership.php? Daha fazla bilgi al]
+	</string>
 	<string name="Open landmarks">
-		Açık yer imleri
+		Açık alanlar
 	</string>
 	<string name="Unconstrained">
-		Kısıtsız
+		Serbest
 	</string>
 	<string name="no_transfer" value="(aktarım yok)"/>
 	<string name="no_modify" value="(deÄŸiÅŸtirme yok)"/>
@@ -5125,6 +5128,9 @@ Hizmetle ilişkili bilinen bir sorun olup olmadığını görmek için lütfen h
 	<string name="Chat">
 		Sohbet
 	</string>
+	<string name="BaseMembership">
+		Temel
+	</string>
 	<string name="DeleteItems">
 		Seçili öğeler silinsin mi?
 	</string>
diff --git a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
index 876fef16dfee3b12d4564b8e6b15ed60fadd3ffd..6ab2220ca724961288c0be4e4492432da75de943 100644
--- a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="COF Attachment">
+	<menu_item_call label="觸碰" name="touch_attach" />
+	<menu_item_call label="編輯" name="edit_item" />
 	<menu_item_call label="卸下" name="detach"/>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml
index 8b65b5c8dee04b79e1c0d084b5d17556e5824f52..10b170d4a44eaeffec7f6f14c9e9ceb61cd4b725 100644
--- a/indra/newview/skins/default/xui/zh/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inventory.xml
@@ -105,6 +105,7 @@
 	<menu_item_call label="穿上" name="Wearable And Object Wear"/>
 	<menu label="附著到..." name="Attach To"/>
 	<menu label="附著到擡頭顯示" name="Attach To HUD"/>
+	<menu_item_call label="觸碰" name="Attachment Touch" />
 	<menu_item_call label="編輯" name="Wearable Edit"/>
 	<menu_item_call label="添加" name="Wearable Add"/>
 	<menu_item_call label="脫下" name="Take Off"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
index 576f7f3b73adbe66a2ce7ee25f05ec6f78625b55..0093eb68f1c3699b27bb9f775796d99a93f57666 100644
--- a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
@@ -3,6 +3,7 @@
 	<menu_item_call label="取代" name="wear_replace"/>
 	<menu_item_call label="穿上" name="wear_wear"/>
 	<menu_item_call label="添加" name="wear_add"/>
+	<menu_item_call label="觸碰" name="touch" />
 	<menu_item_call label="脫下裝扮 / 卸除附件" name="take_off_or_detach"/>
 	<menu_item_call label="卸下" name="detach"/>
 	<context_menu label="附著到..." name="wearable_attach_to"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
index 6184f956d1479d45cb95dd740fdfc566eb26603e..f09d4cfba93f4f91322d653eb94264a3188fc5cc 100644
--- a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <toggleable_menu name="Gear Wearing">
-	<menu_item_call label="編輯裝扮" name="edit"/>
+	<menu_item_call label="觸碰" name="touch"/>
+	<menu_item_call label="編輯" name="edit_item"/>
+	<menu_item_call label="編輯裝扮" name="edit_outfit"/>
 	<menu_item_call label="脫下" name="takeoff"/>
 	<menu_item_call label="複製裝扮清單到剪貼簿" name="copy"/>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
index dc9adcbd25fb49435ca669d433be5ce149cc1d16..945297885ee17c7146fffbe4732fa713a3c2d011 100644
--- a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <context_menu name="Wearing">
+	<menu_item_call label="觸碰" name="touch_attach"/>
 	<menu_item_call label="脫下" name="take_off"/>
 	<menu_item_call label="卸下" name="detach"/>
-	<menu_item_call label="編輯裝扮" name="edit"/>
+	<menu_item_call label="編輯裝扮" name="edit_outfit"/>
 	<menu_item_call label="編輯" name="edit_item"/>
 	<menu_item_call label="顯示原件" name="show_original"/>
 </context_menu>
diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp
index fa4b085fd3a17a760b0bdcf01cc19203d95e3480..e6ccd5ecb7b107e3394a919d4439e06d5f05b1fd 100644
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/test/llpermissions_tut.cpp
@@ -405,43 +405,6 @@ namespace tut
 
 	template<> template<>
 	void permission_object_t::test<20>()
-	{
-		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
-		if(!fp)
-		{
-			LL_ERRS() << "file couldn't be opened\n" << LL_ENDL;
-			return;
-		}
-		LLPermissions perm,perm1;
-		LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");	
-		LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); 
-		LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); 
-		LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");		
-		perm.init(creator,owner,lastOwner,group);
-		
-		U32 base = PERM_TRANSFER | PERM_COPY;
-		U32 ownerp = PERM_TRANSFER;
-		U32 groupp = PERM_TRANSFER;
-		U32 everyone = PERM_TRANSFER;
-		U32 next = PERM_NONE;
-
-		perm.initMasks(base, ownerp, everyone, groupp, next);
-
-		ensure("Permissions export failed", perm.exportFile(fp));
-		fclose(fp);	
-		fp = LLFile::fopen("linden_file.dat","r+");
-		if(!fp)
-		{
-			LL_ERRS() << "file couldn't be opened\n" << LL_ENDL;
-			return;
-		}
-		ensure("Permissions import failed", perm1.importFile(fp));
-		fclose(fp);
-		ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);	
-}
-
-	template<> template<>
-	void permission_object_t::test<21>()
 	{
 		LLPermissions perm,perm1;
 		LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");	
@@ -467,14 +430,7 @@ namespace tut
 	}
 
 	template<> template<>
-	void permission_object_t::test<22>()
-	{
-		// Deleted LLPermissions::exportFileXML() and LLPermissions::importXML()
-		// because I can't find any non-test code references to it. 2009-05-04 JC
-	}
-
-	template<> template<>
-	void permission_object_t::test<23>()
+	void permission_object_t::test<21>()
 	{
 		LLPermissions perm,perm1;
 		LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");	
@@ -490,7 +446,7 @@ namespace tut
 	}
 
 	template<> template<>
-	void permission_object_t::test<24>()
+	void permission_object_t::test<22>()
 	{
 		LLPermissions perm,perm1;
 		LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");	
@@ -513,7 +469,7 @@ namespace tut
 	}
 
 	template<> template<>
-	void permission_object_t::test<25>()
+	void permission_object_t::test<23>()
 	{
 		LLAggregatePermissions AggrPermission;	
 		LLAggregatePermissions AggrPermission1;	
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 5f4d9186a8001a2079d36b979fe8752570047662..b7b207610f3e5fa8b775e09d6ba98c74d9c725ee 100644
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -106,41 +106,6 @@ namespace tut
 
 	template<> template<>
 	void llsaleinfo_test_t::test<2>()
-	{
-
-		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
-		if(!fp)
-		{
-			LL_ERRS() << "file could not be opened\n" << LL_ENDL;
-			return;
-		}
-			
-		S32 sale_price = 43500;
-		LLSaleInfo llsaleinfo(LLSaleInfo::FS_COPY, sale_price);
-		
-		llsaleinfo.exportFile(fp);
-		fclose(fp);
-
-		LLSaleInfo llsaleinfo1;
-		U32 perm_mask;
-		BOOL has_perm_mask;
-		fp = LLFile::fopen("linden_file.dat","r");
-		
-		if(!fp)
-		{
-			LL_ERRS() << "file coudnt be opened\n" << LL_ENDL;
-			return;
-		}
-		
-		llsaleinfo1.importFile(fp, has_perm_mask, perm_mask);
-		fclose(fp);
-		
-		ensure("importFile() fn failed ", llsaleinfo.getSaleType() == llsaleinfo1.getSaleType() &&
-								     llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice());				
-	}
-
-	template<> template<>
-	void llsaleinfo_test_t::test<3>()
 	{
 		S32 sale_price = 525452;
 		LLSaleInfo llsaleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
@@ -160,14 +125,7 @@ namespace tut
 	}
 
 	template<> template<>
-	void llsaleinfo_test_t::test<4>()
-	{
-		// Deleted LLSaleInfo::exportFileXML() and LLSaleInfo::importXML()
-		// because I can't find any non-test code references to it. 2009-05-04 JC
-	}
-
-	template<> template<>
-	void llsaleinfo_test_t::test<5>()
+	void llsaleinfo_test_t::test<3>()
 	{	
 		S32 sale_price = 99000;
 		LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
@@ -186,7 +144,7 @@ namespace tut
 
 	//static EForSale lookup(const char* name) fn test
 	template<> template<>
-	void llsaleinfo_test_t::test<6>()
+	void llsaleinfo_test_t::test<4>()
 	{
 		S32 sale_price = 233223;
 		LLSaleInfo::EForSale ret_type = LLSaleInfo::lookup("orig");
@@ -200,7 +158,7 @@ namespace tut
 
 	//void LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn test
 	template<> template<>
-	void llsaleinfo_test_t::test<7>()
+	void llsaleinfo_test_t::test<5>()
 	{
 		S32 sale_price = 20;
 		LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price);
@@ -213,7 +171,7 @@ namespace tut
 	// test cases of bool operator==(const LLSaleInfo &rhs) fn
 	// test case of bool operator!=(const LLSaleInfo &rhs) fn
 	template<> template<>
-	void llsaleinfo_test_t::test<8>()
+	void llsaleinfo_test_t::test<6>()
 	{
 		S32 sale_price = 55000;
 		LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
@@ -225,7 +183,7 @@ namespace tut
 	}			
 
 	template<> template<>
-	void llsaleinfo_test_t::test<9>()
+	void llsaleinfo_test_t::test<7>()
 	{
 
 		//TBD: void LLSaleInfo::packMessage(LLMessageSystem* msg) const
diff --git a/scripts/code_tools/modified-strings.sh b/scripts/code_tools/modified-strings.sh
new file mode 100644
index 0000000000000000000000000000000000000000..435dda3f5d39b95a7f849efd98bc2b0e228269ad
--- /dev/null
+++ b/scripts/code_tools/modified-strings.sh
@@ -0,0 +1,199 @@
+#!/usr/bin/env bash
+# $LicenseInfo:firstyear=2014&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
+#
+###
+### Extract strings modified between some version and the current version
+###
+
+Action=DEFAULT
+Rev=master
+DefaultXuiDir="indra/newview/skins/default/xui"
+Verbose=false
+ExitStatus=0
+
+while [ $# -ne 0 ]
+do
+    case ${1} in
+        ##
+        ## Show usage
+        ##
+        -h|--help)
+            Action=USAGE
+            ;;
+        
+        -v|--verbose)
+            Verbose=true
+            ;;
+        
+        ##
+        ## Select the revision to compare against
+        ##
+        -r)
+            if [ $# -lt 2 ]
+            then
+                echo "Must specify <revision> with ${1}" 1>&2
+                Action=USAGE
+                ExitStatus=1
+                break
+            else
+                Rev=${2}
+                shift # consume the switch ( for n values, consume n-1 )
+            fi
+            ;;
+
+        ##
+        ## handle an unknown switch
+        ##
+        -*)
+            Action=USAGE
+            ExitStatus=1
+            break
+            ;;
+
+        *)
+            if [ -z "${XuiDir}" ]
+            then
+                XuiDir=${1}
+            else
+                echo "Too many arguments supplied: $@" 1>&2
+                Action=USAGE
+                ExitStatus=1
+                break
+            fi
+            ;;
+    esac           
+
+    shift # always consume 1
+done
+
+progress()
+{
+    if $Verbose
+    then
+        echo $* 1>&2
+    fi
+}
+
+if [[ $ExitStatus -eq 0 && "${Action}" = "DEFAULT" ]]
+then
+    if [[ ! -d "${XuiDir:=$DefaultXuiDir}" ]]
+    then
+        echo "No XUI directory found in '$XuiDir'" 1>&2
+        Action=USAGE
+        ExitStatus=1
+    fi
+fi
+
+if [ "${Action}" = "USAGE" ]
+then
+    cat <<USAGE
+
+Usage:
+    
+    modified-strings.sh [ { -v | --verbose } ] [-r <revision>] [<path-to-xui>]
+
+    where 
+          --verbose shows progress messages on stderr (the command takes a while, so this is reassuring)
+
+          -r <revision> specifies a git revision (branch, tag, commit, or relative specifier)
+                     defaults to 'master' so that comparison is against the HEAD of the released viewer branch
+
+          <path-to-xui> is the path to the root directory for XUI files
+                                    defaults to '$DefaultXuiDir'
+
+    Emits a tab-separated file with these columns:
+    filename
+        the path of a file that has a string change (columns 2 and 3 are empty for lines with a filename)
+    name
+        the name attribute of a string or label whose value changed
+    English value    
+        the current value of the string or label whose value changed
+        for strings, newlines are changed to '\n' and tab characters are changed to '\t' 
+
+    There is also a column for each of the language directories following the English.
+
+USAGE
+    exit $ExitStatus
+fi
+
+stringval() # reads stdin and prints the escaped value of a string for the requested tag
+{
+    local tag=$1
+    xmllint --xpath "string(/strings/string[@name=\"$tag\"])" - | perl -p -e 'chomp; s/\n/\\n/g; s/\t/\\t/g;'
+}
+
+columns="file\tname\tEN"
+for lang in $(ls -1 ${XuiDir})
+do
+    if [[ "$lang" != "en" && -d "${XuiDir}" && -f "${XuiDir}/$lang/strings.xml" ]]
+    then
+        columns+="\t$lang"
+    fi
+done
+echo -e "$columns"
+
+EnglishStrings="${XuiDir}/en/strings.xml"
+progress -n "scanning $EnglishStrings "
+echo -e "$EnglishStrings"
+# loop over all tags in the current version of the strings file
+cat "$EnglishStrings" | xmllint --xpath '/strings/string/@name' - | sed 's/ name="//; s/"$//;' \
+| while read name
+do
+    progress -n "."
+    # fetch the $Rev and current values for each tag
+    old_stringval=$(git show "$Rev:$EnglishStrings" 2> /dev/null | stringval "$name")
+    new_stringval=$(cat           "$EnglishStrings" | stringval "$name")
+
+    if [[ "$old_stringval" != "$new_stringval" ]]
+    then
+        # the value is different, so print the tag and it's current value separated by a tab
+        echo -e "\t$name\t$new_stringval"
+    fi
+done
+progress ""
+
+# loop over all XUI files other than strings.xml finding labels
+grep -rlw 'label' "${XuiDir}/en" | grep -v '/strings.xml' \
+| while read xuipath
+do
+    progress -n "scanning $xuipath "
+    listed_file=false
+    # loop over all elements for which there is a label attribute, getting the name attribute value
+    xmllint --xpath '//*[@label]/@name' "$xuipath" 2> /dev/null | sed 's/ name="//; s/"$//;' \
+    | while read name
+    do
+        progress -n "."
+        # get the old and new label attribute values for each name
+        old_label=$(git show "$Rev:$xuipath" 2> /dev/null | xmllint --xpath "string(//*[@name=\"${name}\"]/@label)" - 2> /dev/null)
+        new_label=$(cat           "$xuipath" | xmllint --xpath "string(//*[@name=\"${name}\"]/@label)" - 2> /dev/null)
+        if [[ "$old_label" != "$new_label" ]]
+        then
+            if ! $listed_file
+            then
+                echo -e "$xuipath"
+                listed_file=true
+            fi
+            echo -e "\t$name\t$new_label"
+        fi
+    done
+    progress ""
+done
+
diff --git a/scripts/code_tools/modified_strings.py b/scripts/code_tools/modified_strings.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a763b6ec54e81ca31e8a12e1bf23932c6646fc5
--- /dev/null
+++ b/scripts/code_tools/modified_strings.py
@@ -0,0 +1,403 @@
+#!/usr/bin/env python
+"""\
+
+This script scans the SL codebase for translation-related strings.
+
+$LicenseInfo:firstyear=2020&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2020, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
+
+from __future__ import print_function
+
+import xml.etree.ElementTree as ET
+import argparse
+import os
+import sys
+from git import Repo, Git # requires the gitpython package
+import pandas as pd
+import re
+from datetime import datetime
+
+usage_msg="""%(prog)s [options]
+
+Analyze the XUI configuration files to find text that may need to
+be translated. Works by comparing two specified revisions, one
+specified by --rev (default HEAD) and one specified by --rev_base
+(default master). The script works by comparing xui contents of the
+two revisions, and outputs a spreadsheet listing any areas of
+difference. The target language must be specified using the --lang
+option. Output is an excel file, which can be used as-is or imported
+into google sheets.
+
+If the --rev revision already contains a translation for the text, it
+will be included in the spreadsheet for reference.
+    
+Normally you would want --rev_base to be the last revision to have
+translations added, and --rev to be the tip of the current
+project. You can find the last commit with translation work using "git log --grep INTL- | head"
+
+The --missing argument can be used to find all text with missing
+translations, regardless of when it was added. If translations are being kept
+reasonably current, you will normally not need this argument.
+"""
+
+translate_attribs = [
+    "title",
+    "short_title",
+    "value",
+    "label",
+    "label_selected",
+    "tool_tip",
+    "ignoretext",
+    "yestext",
+    "notext",
+    "canceltext",
+    "description",
+    "longdescription"
+]
+
+def codify_for_print(val):
+    if isinstance(val, unicode):
+        return val.encode("utf-8")
+    else:
+        return unicode(val, 'utf-8').encode("utf-8")
+
+# Returns a dict of { name => xml_node }
+def read_xml_elements(blob):
+    try:
+        contents = blob.data_stream.read()
+    except:
+        # default - pretend we read a file with no elements of interest.
+        # Parser will complain if it gets no elements at all.
+        contents = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?><strings></strings>'
+    xml = ET.fromstring(contents)
+    elts = {}
+    for child in xml.iter():
+        if "name" in child.attrib:
+            name = child.attrib['name']
+            elts[name] = child
+    return elts
+
+def failure(*msg):
+    print(*msg)
+    sys.exit(1)
+
+# return True iff any element of lis is "in" thing
+def has_any(thing,lis):
+    for l in lis:
+        if l in thing:
+            return True
+    return False
+
+def should_translate(filename, elt, field, val):
+    if val is None:
+        return False
+    # Should translate apply recursively?
+    if "translate" in elt.attrib and elt.attrib["translate"] == "false":
+        return False
+    if has_any(filename,["floater_test","floater_aaa","floater_ui_preview"]):
+        return False
+    if "TestString PleaseIgnore" in val:
+        return False
+    val = re.sub(r"\[.*?\]","",val)
+    if len(val) == 0:
+        return False
+    if val.isspace():
+        return False
+    val = val.strip()
+    if val.isdigit():
+        return False
+    if not re.search('\w+', val):
+        return False
+    if re.match(r"^\s*\d*\s*x\s*\d*\s*$", val):
+        #print(val, "matches resolution string, will ignore")
+        return False
+    # "value" attribute is a hairball, mostly used to encode non-display info but a few exceptions
+    if field == "value":
+        if elt.text is not None and len(elt.text) > 0:
+            #print("value has text, ignoring", ET.tostring(elt))
+            return False
+        if has_any(elt.attrib,["label"]):
+            return False
+        if elt.tag in ["string","text"]:
+            return True
+        #print("including value attribute", val, "tag", elt.tag,"in", ET.tostring(elt))
+        return True
+    return True
+
+def make_translation_table(mod_tree, base_tree, lang, args):
+
+    xui_path = "{}/{}".format(xui_base, args.base_lang)
+    try:
+        mod_xui_tree = mod_tree[xui_path]
+    except:
+        failure("xui tree not found for base language", args.base_lang,"or target lang", lang)
+
+    if args.rev == args.rev_base:
+        failure("Revs are the same, nothing to compare")
+
+
+    data = []
+    # For all files to be checked for translations
+    all_en_strings = set()
+    for mod_blob in mod_xui_tree.traverse():
+        filename = mod_blob.path
+        if mod_blob.type == "tree": # directory, skip
+            continue
+
+        if args.verbose:
+            print(filename)
+
+        try:
+            base_blob = base_tree[filename]
+        except:
+            if args.verbose:
+                print("No matching base file found for", filename)
+            base_blob = None
+
+        try:
+            transl_filename = filename.replace("/xui/{}/".format(args.base_lang), "/xui/{}/".format(lang))
+            transl_blob = mod_tree[transl_filename]
+        except:
+            if args.verbose:
+                print("No matching translation file found at", transl_filename)
+            transl_blob = None
+
+        mod_dict = read_xml_elements(mod_blob)
+        base_dict = read_xml_elements(base_blob)
+        transl_dict = read_xml_elements(transl_blob)
+
+        rows = 0
+        for name in mod_dict.keys():
+            if not name in base_dict or mod_dict[name].text != base_dict[name].text or (args.missing and not name in transl_dict):
+                elt = mod_dict[name]
+                val = elt.text
+                field = "text"
+                if should_translate(filename, elt, field, val):
+                    transl_val = "--"
+                    if name in transl_dict:
+                        transl_val = transl_dict[name].text
+                    if val in all_en_strings:
+                        new_val = "(DUPLICATE)"
+                    else:
+                        new_val = ""
+                    data.append([val, transl_val, new_val, "", "", filename, name, field])
+                    all_en_strings.add(val)
+                    rows += 1
+            for attr in translate_attribs:
+                if attr in mod_dict[name].attrib:
+                    if name not in base_dict \
+                    or attr not in base_dict[name].attrib \
+                    or mod_dict[name].attrib[attr] != base_dict[name].attrib[attr] \
+                    or (args.missing and (not name in transl_dict or not attr in transl_dict[name].attrib)):
+                        elt = mod_dict[name]
+                        val = elt.attrib[attr]
+                        if should_translate(filename, elt, attr, val):
+                            transl_val = "--"
+                            if name in transl_dict and attr in transl_dict[name].attrib:
+                                transl_val = transl_dict[name].attrib[attr]
+                            if val in all_en_strings:
+                                new_val = "(DUPLICATE)"
+                            else:
+                                new_val = ""
+                            #attr = attr + ":" + ET.tostring(elt)
+                            data.append([val, transl_val, new_val, "", "", filename, name, attr])
+                            all_en_strings.add(val)
+                            rows += 1
+
+    return data
+
+def find_deletions(mod_tree, base_tree, lang, args, f):
+
+    transl_xui_path = "{}/{}".format(xui_base, lang)
+    try:
+        transl_xui_tree = mod_tree[transl_xui_path]
+    except:
+        failure("xui tree not found for base language", args.base_lang,"or target lang", lang)
+
+    for transl_blob in transl_xui_tree.traverse():
+        if transl_blob.type == "tree": # directory, skip
+            continue
+        transl_filename = transl_blob.path
+        mod_filename = transl_filename.replace("/xui/{}/".format(lang), "/xui/{}/".format(args.base_lang))
+        #print("checking",transl_filename,"against",mod_filename)
+        try:
+            mod_blob = mod_tree[mod_filename] 
+        except:
+            print("  delete file", transl_filename, file=f)
+            continue
+        mod_dict = read_xml_elements(mod_blob)
+        if len(mod_dict) == 0:
+            print("  delete file", transl_filename, file=f)
+            continue
+        transl_dict = read_xml_elements(transl_blob)
+        #print("mod vs transl", len(mod_dict), len(transl_dict))
+        lines = 0
+        for elt_key in transl_dict:
+            if not elt_key in mod_dict:
+                if lines == 0:
+                    print("  in file", transl_filename, file=f)
+                lines += 1   
+                print("    delete element", elt_key, file=f)
+            else:
+                transl_elt = transl_dict[elt_key]
+                mod_elt = mod_dict[elt_key]
+                for a in transl_elt.attrib:
+                    if not a in mod_elt.attrib:
+                        if lines == 0:
+                            print("  in file", transl_filename, file=f)
+                        lines += 1   
+                        print("    delete attribute", a, "from", elt_key, file=f)
+                if transl_elt.text and (not mod_elt.text):
+                    if lines == 0:
+                        print("  in file", transl_filename, file=f)
+                    lines += 1   
+                    print("    delete text from", elt_key, file=f)
+    
+def save_translation_file(per_lang_data, aux_data, outfile):
+
+    langs = sorted(per_lang_data.keys())
+    print("Saving languages", ",".join(langs),"as",outfile)
+
+    writer = pd.ExcelWriter(outfile, engine='xlsxwriter')
+
+    workbook = writer.book
+    wrap_format = workbook.add_format({'text_wrap': True})
+    bold_wrap_format = workbook.add_format({'text_wrap': True, 'bold': True})
+    wrap_unlocked_format = workbook.add_format({'text_wrap': True, 'locked': False})
+
+    for lang in langs:
+        data = per_lang_data[lang]
+        num_translations = len(data)
+        cols = ["EN", "Previous Translation ({})".format(lang.upper()), "ENTER NEW TRANSLATION ({})".format(lang.upper()), "Translator Questions", "Notes", "File", "Element", "Field"]
+        df = pd.DataFrame(data, columns=cols)
+        df.to_excel(writer, index=False, sheet_name = lang.upper())
+
+        worksheet = writer.sheets[lang.upper()]
+
+        # Translators primarily care about columns A-C, and should write
+        # only in column C. Hide the others. Set widths.
+        worksheet.protect()
+        worksheet.set_column('A:B', 60, wrap_format)
+        worksheet.set_column('C:C', 60, wrap_unlocked_format)
+        worksheet.set_column('D:E', 40, wrap_unlocked_format)
+        worksheet.set_column('F:F', 50, wrap_format, {'hidden': True})
+        worksheet.set_column('G:H', 30, wrap_format, {'hidden': True})
+
+        # Lock the top row (column headers) in place while scrolling
+        worksheet.freeze_panes(1, 0)
+        print("Added", num_translations, "rows for language", lang)
+
+    # Reference info, not for translation
+    for aux, data in aux_data.items():
+        df = pd.DataFrame(data, columns = ["Key", "Value"]) 
+        df.to_excel(writer, index=False, sheet_name=aux)
+        worksheet = writer.sheets[aux]
+        worksheet.set_column('A:A', 50, bold_wrap_format)
+        worksheet.set_column('B:B', 80, wrap_format)
+        
+    print("Writing", outfile)
+    writer.save()
+
+if __name__ == "__main__":
+
+    parser = argparse.ArgumentParser(description="analyze viewer xui files for needed translations", usage=usage_msg)
+    parser.add_argument("-v","--verbose", action="store_true", help="verbose flag")
+    parser.add_argument("--missing", action="store_true", default = False, help="include all fields for which a translation does not exist")
+    parser.add_argument("--deleted", action="store_true", default = False, help="show all translated entities which don't exist in english")
+    parser.add_argument("--skip_spreadsheet", action="store_true", default = False, help="skip creating the translation spreadsheet")
+    parser.add_argument("--rev", help="revision with modified strings, default HEAD", default="HEAD")
+    parser.add_argument("--rev_base", help="previous revision to compare against, default master", default="master")
+    parser.add_argument("--base_lang", help="base language, default en (normally leave unchanged - other values are only useful for testing)", default="en")
+    parser.add_argument("--lang", help="target languages, or 'all_valid' or 'supported'; default is 'supported'", nargs="+", default = ["supported"])
+    args = parser.parse_args()
+
+    cwd = os.getcwd()
+    rootdir = Git(cwd).rev_parse("--show-toplevel")
+    repo = Repo(rootdir)
+    try:
+        mod_commit = repo.commit(args.rev)
+    except:
+        failure(args.rev,"is not a valid commit")
+    try:
+        base_commit = repo.commit(args.rev_base)
+    except:
+        failure(args.rev_base,"is not a valid commit")
+
+    print("Will identify changes in", args.rev, "not present in", args.rev_base)
+    if args.missing:
+        print("Will also include any text for which no corresponding translation exists, regardless of when it was added")
+    sys.stdout.flush()
+
+    mod_tree = mod_commit.tree
+    base_tree = base_commit.tree
+
+    xui_base = "indra/newview/skins/default/xui"
+    xui_base_tree = mod_tree[xui_base]
+
+    # Find target languages
+    # all languages present in the codebase
+    valid_langs = [tree.name.lower() for tree in xui_base_tree if tree.name.lower() != args.base_lang.lower()]
+    # offically supported languages
+    supported_langs = ["fr", "es", "it", "pt", "ja", "de"]
+    langs = [l.lower() for l in args.lang]
+    if "supported" in args.lang:
+        langs = supported_langs
+    if "all_valid" in args.lang:
+        langs = valid_langs
+    langs = sorted(langs)
+    for lang in langs:
+          if not lang in valid_langs:
+              failure("Unknown target language {}. Valid values are {}".format(lang,", ".join(sorted(valid_langs) + ["all_valid","supported"])))
+    print("Target language(s) are", ",".join(sorted(langs)))
+    sys.stdout.flush()
+
+    outfile = "SL_Translations.xlsx"
+    try:
+        f = open(outfile,"a+")
+        f.close()
+    except:
+        failure("Can't write to output file",outfile,". Is it already open?")
+
+    aux_data = { "REFERENCE": [["Command", " ".join(sys.argv)],
+                               ["Date", str(datetime.now())],
+                               ["Mod Commit", mod_commit.hexsha],
+                               ["Base Commit", base_commit.hexsha],
+                              ] }
+
+    if not args.skip_spreadsheet:
+        per_lang_data = {}
+        for lang in langs:
+            print("Creating spreadsheet for language", lang)
+            sys.stdout.flush()
+
+            per_lang_data[lang] = make_translation_table(mod_tree, base_tree, lang, args)
+
+        print("Saving output file", outfile)
+        save_translation_file(per_lang_data, aux_data, outfile)
+
+    if args.deleted:
+        deletion_file = "Translate_deletions.txt"
+        print("Saving deletion info to", deletion_file)
+        with open(deletion_file,"w") as f:
+            for lang in langs:
+                find_deletions(mod_tree, base_tree, lang, args, f)
+