diff --git a/autobuild.xml b/autobuild.xml
index aa4a518fd48224e0e5206bd68b113c252f5c2dc4..eb3adbbe68042690ffdc9659f2005732ab8364ad 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -220,9 +220,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>
@@ -232,9 +232,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>
@@ -244,16 +244,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>
@@ -502,9 +502,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>
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 afba1d7e0236c55259d93d02e30c49d8f71d0c47..cf1ade454fea8f604207281e5922ee761e231faa 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -155,7 +155,7 @@ LLApp::~LLApp()
 		mThreadErrorp = NULL;
 	}
 	
-	SUBSYSTEM_CLEANUP(LLCommon);
+	SUBSYSTEM_CLEANUP_DBG(LLCommon);
 }
 
 // static
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index a2233692c63f7ecc6e13bd59db38597dfa532464..95cd1c4ef7f5717bd9a5b56457baa1dcd753f434 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/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 2a750d80121d9840625e7fa5f52f57e149df77ec..63fb034b6c58b7f3e1e0c974b640167a41c8f475 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");
@@ -224,19 +224,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
-{
-	absl::FPrintF(fp, "\tinv_object\t0\n\t{\n");
-	absl::FPrintF(fp, "\t\tobj_id\t%s\n", mUUID);
-	absl::FPrintF(fp, "\t\tparent_id\t%s\n", mParentUUID);
-	absl::FPrintF(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	absl::FPrintF(fp, "\t\tname\t%s|\n", mName);
-	absl::FPrintF(fp,"\t}\n");
-	return TRUE;
-}
-
 BOOL LLInventoryObject::exportLegacyStream(std::ostream& output_stream, BOOL) const
 {
 	std::string uuid_str;
@@ -592,209 +579,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
-{
-	absl::FPrintF(fp, "\tinv_item\t0\n\t{\n");
-	absl::FPrintF(fp, "\t\titem_id\t%s\n", mUUID);
-	absl::FPrintF(fp, "\t\tparent_id\t%s\n", mParentUUID);
-	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()))
-		{
-			absl::FPrintF(fp, "\t\tasset_id\t%s\n", mAssetUUID);
-		}
-		else
-		{
-			LLUUID shadow_id(mAssetUUID);
-			LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
-			cipher.encrypt(shadow_id.mData, UUID_BYTES);
-			absl::FPrintF(fp, "\t\tshadow_id\t%s\n", shadow_id);
-		}
-	}
-	else
-	{
-		absl::FPrintF(fp, "\t\tasset_id\t%s\n", LLUUID::null);
-	}
-	absl::FPrintF(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
-	if(!inv_type_str.empty()) absl::FPrintF(fp, "\t\tinv_type\t%s\n", inv_type_str);
-	absl::FPrintF(fp, "\t\tflags\t%08x\n", mFlags);
-	mSaleInfo.exportFile(fp);
-	absl::FPrintF(fp, "\t\tname\t%s|\n", mName);
-	absl::FPrintF(fp, "\t\tdesc\t%s|\n", mDescription);
-	absl::FPrintF(fp, "\t\tcreation_date\t%d\n", (S32) mCreationDate);
-	absl::FPrintF(fp,"\t}\n");
-	return TRUE;
-}
-
 // virtual
 BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
 {
@@ -1441,87 +1225,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
-{
-	absl::FPrintF(fp, "\tinv_category\t0\n\t{\n");
-	absl::FPrintF(fp, "\t\tcat_id\t%s\n", mUUID);
-	absl::FPrintF(fp, "\t\tparent_id\t%s\n", mParentUUID);
-	absl::FPrintF(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	absl::FPrintF(fp, "\t\tpref_type\t%s\n", LLFolderType::lookup(mPreferredType).c_str());
-	absl::FPrintF(fp, "\t\tname\t%s|\n", mName.c_str());
-	absl::FPrintF(fp,"\t}\n");
-	return TRUE;
-}
-
-	
 // virtual
 BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream)
 {
@@ -1600,6 +1304,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 d65ca23dca8887a72f812b2a454762116a5f82c3..9e598983cf84391734782861d8e4ab61d0335e5e 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 01299a65849beb1acffd0f6219b9cff77fef80ea..1b994f796d04b581010e4173e6a2667efad30b1e 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 final : public LLDictionaryEntry
@@ -49,7 +45,7 @@ struct SettingsEntry final : 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 3ea782e8edef792d57f5bd4246f82e11ad05548d..43b76e17e7cfbc3edae3f1fe65e353570faf39d6 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -565,139 +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
-{
-	absl::FPrintF(fp, "\tpermissions 0\n");
-	absl::FPrintF(fp, "\t{\n");
-
-	absl::FPrintF(fp, "\t\tbase_mask\t%08x\n",		mMaskBase);
-	absl::FPrintF(fp, "\t\towner_mask\t%08x\n",		mMaskOwner);
-	absl::FPrintF(fp, "\t\tgroup_mask\t%08x\n",		mMaskGroup);
-	absl::FPrintF(fp, "\t\teveryone_mask\t%08x\n",	mMaskEveryone);
-	absl::FPrintF(fp, "\t\tnext_owner_mask\t%08x\n",	mMaskNextOwner);
-
-	absl::FPrintF(fp, "\t\tcreator_id\t%s\n",			mCreator);
-	absl::FPrintF(fp, "\t\towner_id\t%s\n",			mOwner);
-	absl::FPrintF(fp, "\t\tlast_owner_id\t%s\n",		mLastOwner);
-	absl::FPrintF(fp, "\t\tgroup_id\t%s\n",			mGroup);
-
-	if(mIsGroupOwned)
-	{
-		absl::FPrintF(fp, "\t\tgroup_owned\t1\n");
-	}
-	absl::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 e8f5d5f3729eabdb9ceb87767b2addbf306c0923..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
-{
-	absl::FPrintF(fp, "\tsale_info\t0\n\t{\n");
-	absl::FPrintF(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
-	absl::FPrintF(fp, "\t\tsale_price\t%d\n", mSalePrice);
-	absl::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 01678265556d521bd909c130610ee08e666e73f8..72057cff6d244130a2d531ebc4101aa1a6f05bd3 100644
--- a/indra/llinventory/llsettingsbase.h
+++ b/indra/llinventory/llsettingsbase.h
@@ -360,7 +360,6 @@ class LLSettingsBase :
     virtual const parammapping_t& getParameterMap() const;
 
     LLSD        mSettings;
-    bool        mIsValid;
 
     LLSD        cloneSettings() const;
 
diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp
index 054644b129b72d4ef79873078e25b1e0196ff28f..ac32215a7edd19e71214e76dd8fd04ebabac665e 100644
--- a/indra/llinventory/tests/inventorymisc_test.cpp
+++ b/indra/llinventory/tests/inventorymisc_test.cpp
@@ -29,9 +29,9 @@
 #include "linden_common.h"
 #include "llsd.h"
 #include "llrand.h"
+#include "llsdserialize.h"
 
 #include "../llinventory.h"
-
 #include "../test/lltut.h"
 
 
@@ -321,27 +321,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());
@@ -458,27 +470,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 ea03f82741987557e67511e827c637c2344a19b6..c348d274b16a6094078d04a2622e940b6d70f6da 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -371,7 +371,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 e180f3f272b3b43e3a87d058e4dbc456832a23b5..f910b0006e767e4a80bc82f934426ce7eb27d5f2 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -869,12 +869,12 @@ void LLPluginClassMedia::setCEFProgramDirs(const std::string& helper_path,
 }
 
 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 99d5e8cb692aa90f35b92196b443daf1709712ae..2633852a8132dbd9f68abbcfde05e120aec02bb5 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -196,7 +196,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	
 	// These can be called before init(), and they will be queued and sent before the media init message.
 	void	setCEFProgramDirs(const std::string& helper_path, const std::string& resources_path = std::string(), const std::string& locales_path = std::string());
-	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 977b19769fd87f79ec301407785453d8db1d1e95..5f5c587e0af824306f7e2d4a7392e54a2adee538 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2098,10 +2098,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 d63b8daec39848b45f0ab7f361e2dde54cb4282d..02596077fb2c91b4079b41fa1d11a967f366f2a4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1196,7 +1196,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
 		return true;
 	}
 
-	bool sucsess = true;
+	bool success = true;
 
 	mEmpty = true;
 
@@ -1218,9 +1218,9 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
 
 	if (!mMappedData)
 	{
-		sucsess = false;
+		success = false;
 	}
-	return sucsess;
+	return success;
 }
 
 bool LLVertexBuffer::createGLIndices(U32 size)
@@ -1235,7 +1235,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)
 		return true;
 	}
 
-	bool sucsess = true;
+	bool success = true;
 
 	mEmpty = true;
 
@@ -1260,9 +1260,9 @@ bool LLVertexBuffer::createGLIndices(U32 size)
 
 	if (!mMappedIndexData)
 	{
-		sucsess = false;
+		success = false;
 	}
-	return sucsess;
+	return success;
 }
 
 void LLVertexBuffer::destroyGLBuffer()
@@ -1309,7 +1309,7 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
 {
 	llassert(nverts >= 0);
 
-	bool sucsess = true;
+	bool success = true;
 
 	if (nverts > 65536)
 	{
@@ -1321,34 +1321,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)
@@ -1361,10 +1361,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))
 	{
@@ -1380,7 +1380,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 f3b164b3046b344573b1337ec597450aff2b451e..ec44511f81fcc9a8e9a39a1a2feb7560b0555242 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 d38a109b3df80b2660db8d693c09bc09678a8aa6..9a959394b1580228cd97add2aa94a431eb63ab74 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -335,9 +335,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
 void LLFolderView::filter( LLFolderViewFilter& filter )
 {
 	LL_RECORD_BLOCK_TIME(FTM_FILTER);
-	static LLUICachedControl<S32> time_visible("FilterItemsMaxTimePerFrameVisible", 10);
-	static LLUICachedControl<S32> time_invisible("FilterItemsMaxTimePerFrameUnvisible", 1);
-    filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));
+    static LLUICachedControl<S32> filter_visible("FilterItemsMaxTimePerFrameVisible", 10);
+    static LLUICachedControl<S32> filter_hidden("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 91cdef420ac44fc9ee26dc31423027a31c574d93..46df5d892608c579ba6c4367d438abaf45037edc 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -124,6 +124,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 :	LLView(p),
 	mLabelWidth(0),
 	mLabelWidthDirty(false),
+    mSuffixNeedsRefresh(false),
     mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
 	mParentFolder( NULL ),
 	mIsSelected( FALSE ),
@@ -183,11 +184,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;
@@ -282,24 +297,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
@@ -350,6 +392,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 fbb6c7aa385fbd452181fc8cd1af0ddb4a27a5af..bc8c00960906bc432ab8fc914731dd32cdd44b24 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -48,8 +48,8 @@ std::string LLFolderViewModelCommon::getStatusText()
 
 void LLFolderViewModelCommon::filter()
 {
-    static LLUICachedControl<S32> max_time("FilterItemsMaxTimePerFrameVisible", 10);
-    getFilter().resetTime(llclamp(max_time(), 1, 100));
+    static LLUICachedControl<S32> filter_visible("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 1bc3e928a10ad6b240030f261ba9b42d7ca7523e..607aa8bccbdb83f4ffc81f1ac196ac9163522b78 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -285,13 +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
-		
-		if(child->getParent() == this)
-			return;
-
+	{
 		mChildren.push_back(child);
 		child->setParent(this); 
 		dirtyFilter();
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
index 7baf0012d71daa9bff25beec578be92545f29701..dca99a6705f63e61d86b719c6d7ebd31fadd7dc6 100644
--- a/indra/llui/llspellcheck.cpp
+++ b/indra/llui/llspellcheck.cpp
@@ -45,8 +45,6 @@ LLSpellChecker::settings_change_signal_t LLSpellChecker::sSettingsChangeSignal;
 LLSpellChecker::LLSpellChecker()
 	: mHunspell(NULL)
 {
-	// Load initial dictionary information
-	refreshDictionaryMap();
 }
 
 LLSpellChecker::~LLSpellChecker()
@@ -54,6 +52,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)) )
diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h
index 0e4d96561cb9d28944836df055dce2bdd240eed6..2326b0d731fce83832a14d9c442b6ed6e33f321f 100644
--- a/indra/llui/llspellcheck.h
+++ b/indra/llui/llspellcheck.h
@@ -47,6 +47,7 @@ class LLSpellChecker final : 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 b1a197ec6cd641b0a7bb3bfb10ec265244337b0f..b7fc6d19eacf326dd2d7b70b8c3d1a71bec152c9 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 d2ff42e8e2bd3c980473b5c2d35b4413bdf6d6f4..0e7b331a23f4cfe6bfc79a931f15f48dfe1e5a2d 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -866,9 +866,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);
@@ -914,16 +911,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;
 }
@@ -1230,7 +1235,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,
@@ -1554,6 +1562,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 				oldDC = mhDC;
 				mhDC = nullptr;											// Zero The Device Context
 			}
+
+        // Destroy The Window
 			oldWND = mWindowHandle;
 		}
 
@@ -3514,7 +3524,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 ecd48daee2f893490dd7e01fccdd1f641f2fc207..5efb59c21ddb58aa438bc6fb80a11e68973e8058 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -101,7 +101,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;
@@ -461,7 +463,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")
@@ -530,7 +531,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
@@ -599,9 +602,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/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 e2c08faf620a85108eff0ce8f9b5960f9e049d06..d9d7688d1f8dda245de060f390c7a915826154e1 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 3c3c1a286b4d2156d8e738a096f0b0d2ea75d9bb..1a007086443636624bfa5116e23404d881ccb16e 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -142,6 +142,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;
@@ -153,12 +157,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();
@@ -177,6 +188,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();
@@ -194,6 +207,8 @@ class LLTeleportRequestViaLocation : public LLTeleportRequest
 	LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
 	virtual ~LLTeleportRequestViaLocation();
 
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport();
@@ -216,6 +231,8 @@ class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation
 //	LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
 	virtual ~LLTeleportRequestViaLocationLookAt();
 
+	virtual void toOstream(std::ostream& os) const;
+
 	virtual bool canRestartTeleport();
 
 	virtual void startTeleport();
@@ -515,6 +532,8 @@ void LLAgent::init()
 void LLAgent::cleanup()
 {
 	mRegionp = NULL;
+    mTeleportRequest = NULL;
+    mTeleportCanceled = NULL;
 	if (mTeleportFinishedSlot.connected())
 	{
 		mTeleportFinishedSlot.disconnect();
@@ -917,9 +936,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 	if (mRegionp != regionp)
 	{
 
-		std::string ip = regionp->getHost().getString();
-		LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName()
-				<< " located at " << ip << 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.
@@ -2710,6 +2732,7 @@ void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
 		else
 		{
 			mMaturityPreferenceNumRetries = 0;
+			LL_WARNS() << "Too many retries for maturity preference" << LL_ENDL;
 			reportPreferredMaturityError();
 		}
 	}
@@ -2761,6 +2784,7 @@ void LLAgent::reportPreferredMaturityError()
 	mIsMaturityRatingChangingDuringTeleport = false;
 	if (hasPendingTeleportRequest())
 	{
+		LL_WARNS("Teleport") << "Teleport failing due to preferred maturity error" << LL_ENDL;
 		setTeleportState(LLAgent::TELEPORT_NONE);
 	}
 
@@ -3898,7 +3922,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;
@@ -3964,11 +3988,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
@@ -4035,6 +4061,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
@@ -4078,10 +4105,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));
         }
     }
@@ -4119,6 +4155,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();
 }
@@ -4135,8 +4183,8 @@ void LLAgent::teleportRequest(const U64& region_handle, const LLVector3& pos_loc
 	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);
@@ -4179,6 +4227,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);
@@ -4211,6 +4264,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);
@@ -4233,6 +4291,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");
@@ -4245,13 +4305,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();
@@ -4305,7 +4366,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);
@@ -4325,6 +4385,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();
 	}
 }
@@ -4403,7 +4471,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 && LLPipeline::FreezeTime)
 	{
@@ -4740,6 +4812,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;
@@ -4863,40 +4963,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
 //-----------------------------------------------------------------------------
@@ -4913,6 +5043,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
@@ -4953,6 +5089,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;
@@ -4993,6 +5135,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 4ba4683d072bc02ecaa3db7ed6d439264988a4b4..e9f33099fdbe9f10de81995e7e70baa3224e784d 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
 //------------------------------------------------------------------------
@@ -632,6 +625,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 5e945906a329132d4f955efb09ce81e5606a513b..cd02115609037764e228ae4bba0dc32072745ea3 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -917,13 +917,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 f472568dbc06626abd96226ca65a670ee7009864..08c61fcfd95133f91c150486c3345e921b686673 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 200af0c67ff32d09cd695c90cef8e2d263432e2f..fbacf418c021d2765de43ed390b5b99b82b905ec 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 b47cd8f77f390a62527da96d4a4f96e9d1b75b5f..689ce1f1c4d0352e4b2b18b4d2cc2b5ee71f196c 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3636,6 +3636,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 15f8bc2a2e2d884be7355680e227875af907171c..aea71a99b75ae14e47871ab43f3a8776a7752c7e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -542,7 +542,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;
@@ -620,8 +621,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;
@@ -792,7 +794,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();
@@ -1037,13 +1039,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())
 	{
@@ -1516,8 +1532,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);
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
index 5b4919b216a09235bfb6e674220c309b21747739..b311d14f613b435efc6d65d002270b21d8ec85cf 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 32716753088e87eb0d93087d3b701dc3cf548ed0..9dfee681fad1886f153e0bcc537d3628fa0d326f 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 96e4fc3cc7cc8f6b9e8e147160f73a858e02af0a..e4bdc94f8ece10e8b01ff54592b2a586fde5fad3 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 631e983444ce6769dc3e4468091e2b3fcc519b14..5eb98222bd5cb944f544f619fefe4ec63b174c9e 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -58,7 +58,6 @@
 #include "llinventorymodel.h"
 #include "llmultigesture.h"
 #include "llui.h"
-#include "llviewermenu.h"
 #include "lluictrlfactory.h"
 // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0b)
 #include "rlvactions.h"
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 2173347c0f0f761831040a546675265322698f2c..d7221431a08ba600191b1ce7c2820c88249a46b2 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -65,6 +65,7 @@
 #include "llstring.h"
 #include "llurlaction.h"
 #include "llviewercontrol.h"
+#include "llviewermenu.h"
 #include "llviewerobjectlist.h"
 // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f)
 #include "rlvactions.h"
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 7e6db3652aae6ef23bb7166625e8fe431cb8363c..80525c04fa892978acf6cb928d6200a81a5aacbc 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 bf977002f335c25d26b3c4e423074aec996c2f09..d50b9f4955ac8f05612a04472cf7ac6deb60ebb5 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 c6bb16e56970787d2c0775ccc9a9071ca62ee196..86bff3f6e995464dc573e9c7ab59c37bd4f66ebb 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"
 // [SL:KB] - Patch: UI-Notifications | Checked: 2013-05-09 (Catznip-3.5)
 #include "llchannelmanager.h"
 // [/SL:KB]
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 480f6096e2ea2ca14d191267f91195a93024d164..9f6446f3d760d7da4435d571880702c425842068 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 1c3cb12c86c3edd128feb014b65e27356227ea26..d8b48927228c351cee980db4139b820928553838 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -36,7 +36,6 @@
 // Classes
 //
 class LLColor4;
-class LLFloaterColorPicker;
 
 class LLColorSwatchCtrl final
 : public LLUICtrl
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 0074e36593421df046689e5599eda6a2efe70bbc..6a553979bbc138ef54e7a4d28a51d3bf895a5e71 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 f08aeac5f804aa3ae94da7a47cc4538e8fc655f5..0ed3b62e10133a7d0c1b838a71461122dfc3e4d5 100644
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
@@ -29,13 +29,10 @@
 
 #include "llinventory.h"
 #include "llviewerobject.h"
-#include "llvoinventorylistener.h"
 #include "lluuid.h"
 
 #include "llfloater.h"
 
-#include "llviewerinventory.h"
-
 #include "llevents.h"
 
 class LLScrollListCtrl;
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index c0f10b4f5f7580cb0045629452fb2cd1d9bcb57b..ca40866611b872e67a2ada8102b58ce1ebc6a5dc 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -90,6 +90,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 653be3b2593c3395e639963680b6b7a9004af1aa..a3342c66afdfdb671ec1229b2d2a283e0d753ac3 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -427,7 +427,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());
@@ -542,7 +542,9 @@ BOOL LLConversationViewParticipant::postBuild()
     }
 
     updateChildren();
-	return LLFolderViewItem::postBuild();
+	LLFolderViewItem::postBuild();
+    refresh();
+    return TRUE;
 }
 
 void LLConversationViewParticipant::draw()
@@ -616,7 +618,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 f760ab17c6a3551134892040b86c86538cb7764e..6f4bc9ff855e6a5f3c8f1bccf4aebdee5bc79761 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 60318a4acc12f8428e1ff6deb2938cd2341e57a4..d2cde6fc381f7ce0bd1cc110cc7af71da5b9be1f 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -160,7 +160,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 9c6d1c778bc4ab1f1c5fdead024e2f255aa44296..9f330385044efc3f9bab4448f6e78bfaab82a8c5 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -810,6 +810,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
@@ -1066,6 +1086,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)
@@ -1102,11 +1123,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();
@@ -1123,7 +1146,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;
     }
 
@@ -1132,30 +1155,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)
@@ -1228,10 +1253,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);
@@ -1245,19 +1272,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();
     }
 
@@ -1273,7 +1329,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);
     }
 
@@ -1289,7 +1345,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);
     }
 
@@ -1332,7 +1388,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();
     }
 
@@ -2368,7 +2424,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;
     }
@@ -3339,7 +3395,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 d5d3e104e22a4921cb6d30845d3d31113a41c277..e8126ca8fe51e2878c6820a6b261c5a4835cd357 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -148,8 +148,11 @@ class LLEnvironment final : 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 141c7f7518e7b96f2286040b25d91a4f9d17f1dc..862c46d50c2eeead5af78626ae07f5e5092e6580 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -55,6 +55,7 @@
 #include "llcallbacklist.h"
 #include "llworld.h"
 #include "llsdserialize.h"
+#include "llviewermenu.h" // is_agent_mappable
 #include "llviewerobjectlist.h"
 // [RLVa:KB] - @pay
 #include "rlvactions.h"
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 2c289ed286affa1d8fb49d5d02f97fbf4d7cb89e..0128777f6efa63f6b38a899175dd795b5dfe678d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1600,9 +1600,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") &&
@@ -1632,7 +1634,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");
@@ -1687,6 +1692,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 8683f4fc7cbf1c28119c49378510b537140e53d4..0e5d4c1c10d291cae0385da6257f4b7b95a04060 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 a7278fb0474605c38c7905387caa1fdab83a8e7b..709ec22b14807af76e6b52a4d2b0d126b73735b0 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 67490e2e0999e0d8aaa8686a994ad2e4a96ebd17..ec086b8f4c59132102d54dbc36c30070e6e7e3ec 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -106,7 +106,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 48ae0058fd7b195fe9682acfbf8597fd1429fb07..1623999b1a858bc1684e47de2f9a726f4af49a09 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -591,7 +591,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 13b4628cb572fc15070d226ed4a9b258648cbdeb..dc1170272bb3fc7dcc54f14415f368c248994366 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -6484,6 +6484,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);
@@ -6663,6 +6671,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"));
 // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
 				if ( (rlv_handler_t::isEnabled()) && (!gRlvAttachmentLocks.canDetach(item)) )
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d5244bc9828d44dfba3f42054763f6890671f3ec..e94ad6eafd16d6483e6767de571ddef8194b9858 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"
@@ -672,6 +673,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 cb44d0966de86c0d1fb65fb6bbe19298ca20ccf8..ce82108103c5cd38da6f2f5247acb7c8ad960848 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 32054a79baf1ac5ea0a971faf1dd629215a76258..c3c801f45617c659a4f00b2bd215088524d71995 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"
@@ -80,8 +81,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
@@ -734,17 +735,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)
     {
@@ -1008,16 +1051,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)
@@ -2767,29 +2823,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;
@@ -2797,43 +2861,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
 				{
@@ -2846,61 +2900,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;
-	LLUniqueFile 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;
 	}
 
-	absl::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;
 	}
 
+	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 50299cc748538dba47f804966f3ef8a15f3ef55c..507dbb7cd968ccc980a0919060863d02bb2100f4 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -150,7 +150,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),
@@ -521,7 +521,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);
@@ -564,7 +575,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())
 			{
@@ -861,7 +878,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);
 }
 
@@ -871,11 +888,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;
@@ -896,7 +945,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;
@@ -905,7 +954,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;
 
@@ -982,26 +1031,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);
@@ -1837,21 +1912,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 ab7a92d91d0685d895167273648f9a92fff54442..f2457aba697d7105e4a437750372269e794381d2 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -132,6 +132,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 final : public LLSingleton<LLLogChatTimeScanner>
 {
 	LLSINGLETON(LLLogChatTimeScanner);
@@ -412,7 +422,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])
@@ -797,7 +807,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;
 			}
@@ -1118,7 +1128,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 1687cde50f4468057c064caa85ceb152ad85deb0..0ed10789ad404d1cd76b7d811712992d7a4fb5e6 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -100,7 +100,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
@@ -1941,6 +1941,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;
 		}
@@ -2893,12 +2899,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);
 		}
@@ -3270,7 +3276,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")
@@ -3291,6 +3296,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());
 
+            // 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; 
 
 		
@@ -3325,6 +3334,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)
@@ -4229,42 +4240,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 68419a8220f2b65d81130fb7915b893cabe520de..7be5afb7b116ef0d20f9b98121fda6f16c95cac4 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -346,7 +346,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);
@@ -600,9 +600,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 ac3f34c740e5a22f0b19953bd03499c64f8d9bbb..d8f8be55156a67f395054667a8ccee9454ecc88b 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/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index dbda6070fa5b326bec024643dc2bd508ecfacd84..c4c6255d2e9a3087b62f7ef9312f576cd37d1301 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -30,6 +30,7 @@
 #include "llagent.h"
 #include "llloadingindicator.h"
 #include "lltooldraganddrop.h"
+#include "llviewermenu.h" // is_agent_mappable
 
 //////////////////////////////////////////////////////////////////////////
 // LLProfileDropTarget
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 00bef31fc519045c7a3557f16199c1295fae4d56..6ac466b45f7f23265d8ddddc5be1f256b01ad275 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -231,6 +231,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 d22e4aad7a658201ee9b337f651d6f4dc43df312..60723505b54073821cdc73dd5f99764d181b4f58 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 c25c5d8b90290d2e08ebeaa756e9141a7b69eb17..256529036727f162d652243e8b98001f7e0518c3 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -107,8 +107,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");
@@ -186,7 +184,6 @@ void LLPanelPlaceProfile::resetLocation()
 	mYouAreHerePanel->setVisible(FALSE);
 
 	std::string loading = LLTrans::getString("LoadingData");
-	mParcelOwner->setValue(loading);
 
 	mParcelRatingIcon->setValue(loading);
 	mParcelRatingText->setText(loading);
@@ -251,14 +248,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());
@@ -404,6 +401,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 043e739457f6aeb5f5ad40ac015c77a6697c6036..2ce7562dbe67ffa48c7cdc0f607201267c019139 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)
@@ -1215,13 +1215,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 7b750fe1d5a0c93be7cda1e818523b7242a2d8b9..2c312dbff97f5631e41e3b354168b212c62aeb3e 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -68,7 +68,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));
 
@@ -82,6 +84,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;
@@ -96,7 +108,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));
@@ -154,18 +168,23 @@ class LLWearingContextMenu : public LLListContextMenu
 // [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
 		bool rlv_blocked = (mUUIDs.size() == rlv_locked_count);
 // [/RLVa:KB]
+		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);
 // [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7)
 		menu->setItemEnabled("take_off",	!rlv_blocked);
 		menu->setItemEnabled("detach",		!rlv_blocked);
 // [/RLVa:KB]
-		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);
 	}
 };
 
@@ -193,12 +212,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;
@@ -370,6 +392,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 e82290d991f245e8c20985b99d1e7007c54bf6ea..f037ba8840ef46775772817d5dc47b852b3c7cba 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -308,6 +308,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 e6a940624d980e1b32a3ab5d1eb3e65e5dedbc60..795bdab2bdce76ff6d3df17afe9b4e64955eca31 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 cfc0012adeb0ff52b3b3951589bbbd0a9d501cf0..4c5cb253d3d711a34f851265b4b2dbfc220c3c80 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 3fa43c9c948286551e917b25916af31bf9946107..54e6d9c1e6b4e77ad6c5a56f81fbb63d275c49fb 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -156,7 +156,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)
@@ -344,7 +344,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
@@ -392,7 +392,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);
@@ -436,7 +436,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
@@ -581,7 +581,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
@@ -629,7 +629,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
@@ -649,7 +649,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;
 	}
 
@@ -680,7 +680,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 = ALControlCache::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.
@@ -696,7 +696,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;
@@ -746,7 +746,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())
@@ -837,7 +837,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(
@@ -925,13 +925,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)
         {
@@ -959,7 +959,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);
 }
@@ -981,7 +981,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();
@@ -1004,12 +1004,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))
 	{
@@ -1037,7 +1037,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 de0c685ccb63d09b3a67c3fb7cabd9dedb4dea67..bad16bb3ad1982b5dba21b6c10300b56d657995f 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3126,13 +3126,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;
@@ -3358,7 +3358,7 @@ class LLOctreeRenderNonOccluded : public OctreeTraveler
 		for (OctreeNode::const_element_iter i = branch->getDataBegin(), i_end = branch->getDataEnd(); i != i_end; ++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 9cccf22b8d0cbb04b77d20678c5a41c495268d72..3f1fa4be6d1ae57c6dba828037465cc428e169d2 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1259,7 +1259,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/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 8635a146ab4476d889bcd91171dbffa8f412dd1a..79dc553828f23bc1c89898484ce66369785cacd7 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -616,6 +616,9 @@ bool LLTextureCacheRemoteWorker::doWrite()
 			if(idx >= 0)
 			{
 				// write to the fast cache.
+                // mRawImage is not entirely safe here since it is a pointer to one owned by cache worker,
+                // it could have been retrieved via getRequestFinished() and then modified.
+                // If writeToFastCache crashes, something is wrong around fetch worker.
 				if(!mCache->writeToFastCache(mID, idx, mRawImage, mRawDiscardLevel))
 				{
 					LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
@@ -2161,8 +2164,8 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
 		h >>= i;
 		if(w * h *c > 0) //valid
 		{
-			//make a duplicate to keep the original raw image untouched.
-
+            // Make a duplicate to keep the original raw image untouched.
+            // Might be good idea to do a copy during writeToCache() call instead of here
             try
             {
 #if LL_WINDOWS
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index a73df1e89d34def9c86e23ca8a8d48f424e8802f..c3821175a02a948535e81a63fddad6152df90785 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2011,6 +2011,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		setState(WAIT_ON_WRITE);
 		++mCacheWriteCount;
 		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
+        // This call might be under work mutex, but mRawImage is not nessesary safe here.
+        // If something retrieves it via getRequestFinished() and modifies, image won't
+        // be protected by work mutex and won't be safe to use here nor in cache worker.
+        // So make sure users of getRequestFinished() does not attempt to modify image while
+        // fetcher is working
 		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
 																  mFormattedImage->getData(), datasize,
 																  mFileSize, mRawImage, mDecodedDiscard, responder);
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 839cc366af5ae6c6a039b2870c175cdb7e67231a..d922610d4016718e820ff0b43e17f534edf6b1d8 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -92,6 +92,7 @@ class LLTextureFetch : public LLWorkerThread
 	void deleteAllRequests();
 
 	// Threads:  T*
+	// keep in mind that if fetcher isn't done, it still might need original raw image
 	bool getRequestFinished(const LLUUID& id, S32& discard_level,
 							LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux,
 							LLCore::HttpStatus& last_http_get_status);
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 6fc15c321d1830476da0b434b6308173230e6443..8b19e04620de86becc618eafd655ecdde271cc0a 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -200,6 +200,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 82f20f6ab07daf6cc89a1c07ac34035b05cc12da..c971650ef4ef4f079c2e9f5825beaaaa872fc6e1 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -455,6 +455,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(LLStringUtil::null);
 		}
@@ -476,6 +477,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"]);
@@ -500,6 +502,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"]);
@@ -516,6 +519,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"));
@@ -531,6 +535,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 eb4b50239122d9e143f6384247fe7cc4849cc16e..020a3c9494987409632357f173e2ecf9bf081660 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -84,6 +84,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
@@ -525,14 +528,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)
 {
@@ -541,29 +536,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
-{
-	absl::FPrintF(fp, "\tinv_item\t0\n\t{\n");
-	absl::FPrintF(fp, "\t\titem_id\t%s\n", mUUID);
-	absl::FPrintF(fp, "\t\tparent_id\t%s\n", mParentUUID);
-	mPermissions.exportFile(fp);
-	absl::FPrintF(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
-	if(!inv_type_str.empty()) absl::FPrintF(fp, "\t\tinv_type\t%s\n", inv_type_str);
-	absl::FPrintF(fp, "\t\tname\t%s|\n", mName);
-	absl::FPrintF(fp, "\t\tcreation_date\t%d\n", (S32) mCreationDate);
-	absl::FPrintF(fp,"\t}\n");
-	return true;
-}
-
 void LLViewerInventoryItem::updateParentOnServer(BOOL restamp) const
 {
 	LLMessageSystem* msg = gMessageSystem;
@@ -724,86 +696,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
+bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data)
 {
-	absl::FPrintF(fp, "\tinv_category\t0\n\t{\n");
-	absl::FPrintF(fp, "\t\tcat_id\t%s\n", mUUID);
-	absl::FPrintF(fp, "\t\tparent_id\t%s\n", mParentUUID);
-	absl::FPrintF(fp, "\t\ttype\t%s\n", LLAssetType::lookup(mType));
-	absl::FPrintF(fp, "\t\tpref_type\t%s\n", LLFolderType::lookup(mPreferredType));
-	absl::FPrintF(fp, "\t\tname\t%s|\n", mName);
-	absl::FPrintF(fp, "\t\towner_id\t%s\n", mOwnerID);
-	absl::FPrintF(fp, "\t\tversion\t%d\n", mVersion);
-	absl::FPrintF(fp,"\t}\n");
+	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 17c163ad021d693c0f692db4dbaa9fe0d303dd83..78f04f8bafdad12e414c493da3da657375fc7dae 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 10f103251f9a5d335c431d592c10edc5c97e892e..3d4a38289b67499321ffaf30f78769cc43c1b307 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1723,23 +1723,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))
@@ -1760,7 +1745,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			std::string subprocess_folder = gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter();
 			media_source->setCEFProgramDirs(subprocess_folder);
 #endif
-			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 04ef12ed71694240adae9ef0aed295fa2a19e59a..369f3ce14554572f82c73b123285363c6c53e52a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -397,20 +397,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
@@ -2852,7 +2838,6 @@ class LLObjectBuild : public view_listener_t
 	}
 };
 
-
 void handle_object_edit()
 {
 	LLViewerParcelMgr::getInstance()->deselectLand();
@@ -2897,6 +2882,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 12fb2b354f3d0db8d4bd2f03f659f2449f3ec467..a51cfe75c19da9e503c66f81b104a1e15053076b 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -88,7 +88,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);
@@ -116,6 +115,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 733fd8190c7f9bfb07b6875a1d98fa677a10379b..682edfd296bfc058a8138545ca47b6b9f6faf83c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -422,6 +422,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);
@@ -3151,12 +3152,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;
 	}
 
@@ -3166,12 +3167,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);
@@ -3180,7 +3182,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.
@@ -3211,11 +3213,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()))
@@ -3257,7 +3266,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);
@@ -3266,11 +3275,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);
 
@@ -3306,6 +3316,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;
 
@@ -3315,13 +3327,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;
@@ -3338,7 +3350,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;
@@ -3348,19 +3360,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.
@@ -3388,6 +3402,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())
@@ -3401,6 +3416,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)
@@ -6363,6 +6380,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;
@@ -6381,6 +6400,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;
@@ -6390,10 +6410,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();
@@ -6409,6 +6430,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;
@@ -6431,22 +6453,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;
 	}
 
@@ -6458,6 +6485,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 )
@@ -6470,6 +6498,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 4828cf0ea20918e63101dd7ff9fa7c2174361be1..88185d915d0f257a1ca35771d10a01245a342e42 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4862,9 +4862,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 f224851e6bd87ca9f35c8f4a303553b95a1df956..87c3acb5b9e35d62f1a5e4310f3f31651474893d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -115,7 +115,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 9ae17900f0ca609c24e02da884d123a7280680bd..99f0b285861b0f65803c6dbf2040f87f62b32638 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -292,6 +292,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;
 
@@ -351,9 +352,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 24c9b39a3c29eeaefd3f87ac58a48fe72b851cb2..b5e46aaa576672ebad32c722edcdcb0250ea2189 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -393,6 +393,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/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d6befa26aed984b8e880311ead44ad1edd20dc10..8e8f979a437fe6f6734d0eacdc2c1b98602f736b 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1251,6 +1251,8 @@ void LLViewerFetchedTexture::loadFromFastCache()
 		{
             if (mBoostLevel == LLGLTexture::BOOST_ICON)
             {
+                // Shouldn't do anything usefull since texures in fast cache are 16x16,
+                // it is here in case fast cache changes.
                 S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
                 S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
                 if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
@@ -1498,7 +1500,8 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 		mOrigWidth = mRawImage->getWidth();
 		mOrigHeight = mRawImage->getHeight();
 
-			
+        // This is only safe because it's a local image and fetcher doesn't use raw data
+        // from local images, but this might become unsafe in case of changes to fetcher
 		if (mBoostLevel == BOOST_PREVIEW)
 		{ 
 			mRawImage->biasedScaleToPowerOfTwo(1024);
@@ -2004,6 +2007,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		
 		if (mRawImage.notNull()) sRawCount--;
 		if (mAuxRawImage.notNull()) sAuxCount--;
+		// keep in mind that fetcher still might need raw image, don't modify original
 		bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage,
 																		   mLastHttpGetStatus);
 		if (mRawImage.notNull()) sRawCount++;
@@ -2063,7 +2067,8 @@ bool LLViewerFetchedTexture::updateFetch()
                     if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
                     {
                         // scale oversized icon, no need to give more work to gl
-                        mRawImage->scale(expected_width, expected_height);
+                        // since we got mRawImage from thread worker and image may be in use (ex: writing cache), make a copy
+                        mRawImage = mRawImage->scaled(expected_width, expected_height);
                     }
                 }
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1aa7871f2968994b59f6e829ab97048721f29596..0ce577f6bc36ce3002ca8a7d516a76cfe4201ae8 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -347,6 +347,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;
@@ -2338,7 +2344,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 2cfa45584a4356e948f3507bb041ba97c9424f1a..850f8585c8ba1b4e5c4e25ae7fec6912bc5c83ec 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 89d8e8f7266f039db2ffa0e316aaba38340a0ffa..5b2f10c40733e883810660b163a96cad0a089950 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -499,9 +499,13 @@ class LLVoiceClient final : public LLParamSingleton<LLVoiceClient>
  **/
 class LLSpeakerVolumeStorage final : 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 b7eae9b3b67078f0362e5b2856725dcafd765bf0..2b2e40002dbe3ab4c27a5a90e022770b9658573c 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1751,6 +1751,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 df3ec565a21d8574081a28654a676fd7f68ae78c..8f20d1b12bbdedd2ba2b6a9d9addb36adfc85777 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -242,7 +242,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()
@@ -1421,6 +1422,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 06a7d24bc2aab4b8f55d7f9b5155fdc71dc1eb04..79b6a502ac784cfe31d1c792625b45704bfafe32 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -430,6 +430,8 @@ class LLVOVolume final : public LLViewerObject
 	S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
 	S32 mMDCImplCount;
 
+	bool mResetDebugText;
+
 	LLPointer<LLRiggedVolume> mRiggedVolume;
 
 	bool hasSkinInfoFailed() const { return mSkinInfoFailed; }
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index faed88558d431ffa1c691a74df1c750663c545d4..879686d1c5d3c58679ace037e38df62c81a7a065 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 6fac4cef6298c3da1e7c5f88a75add080f097f49..749d35ac1aa3552e2a966b0ae11e898c1c29143c 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"
 // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
 #include "rlvactions.h"
@@ -798,7 +799,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", 
@@ -813,6 +814,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));
 
@@ -842,6 +844,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;
 
@@ -869,12 +872,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;
@@ -932,8 +940,10 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
 	setMenuItemEnabled(menu, "wear_replace",		rlvCanWearReplace);
 // [/RLVa:KB]
 	//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 22bbe5618455c6dbd831c96ab1de6038c090fb0b..95345aa990de48c1061d2093bca5c3d4f96e4024 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -337,6 +337,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;
@@ -1080,6 +1081,12 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
 	return true;
 }
 
+//static
+void LLPipeline::updateRenderTransparentWater()
+{
+    sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
+}
+
 //static
 void LLPipeline::updateRenderBump()
 {
@@ -1093,6 +1100,7 @@ void LLPipeline::updateRenderDeferred()
                       RenderDeferred &&
                       LLRenderTarget::sUseFBO &&
                       LLPipeline::sRenderBump &&
+                      LLPipeline::sRenderTransparentWater &&
                       RenderAvatarVP &&
                       WindLightUseAtmosShaders &&
                       (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
@@ -6038,25 +6046,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;
 }
@@ -6075,13 +6076,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 (const Light& light : mNearbyLights)
@@ -6113,10 +6119,40 @@ 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 = std::move(cur_nearby_lights);
+		mNearbyLights = cur_nearby_lights;
 				
 		// FIND NEW LIGHTS THAT ARE IN RANGE
 		light_set_t new_nearby_lights;
@@ -6131,17 +6167,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();
@@ -6152,7 +6194,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 		// INSERT ANY NEW LIGHTS
 		for (const Light& light : new_nearby_lights)
 		{
-			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);
@@ -6165,10 +6207,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
 				{
@@ -6286,12 +6340,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);
@@ -8653,10 +8701,13 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
                 mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
                 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-				for (LLDrawable* drawablep : mLights)
+                // 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)
                 {
-					
-                    LLVOVolume *volume = drawablep->getVOVolume();
+                    LLDrawable * drawablep = iter->drawable;
+                    LLVOVolume * volume = drawablep->getVOVolume();
                     if (!volume)
                     {
                         continue;
@@ -8670,24 +8721,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, camera.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 46c2e9909ede4d946db26221fd3b1d03b015cdb6..e89b2b75f2922f4a7548a365fb8df1dd6e8c88be 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/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index f77909ae7912de7b649dace3297a46929026a66c..fa93bd03223100f01306960a3ac10a385f3b26cb 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 5c6b5e4e4ce94c039dfd4675a3ca8d1d9a5f4e7b..bd1f4f324e9ef728cb4757302c2241aad10014b8 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"
@@ -9580,6 +9580,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.
 
@@ -10302,7 +10308,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)
+