diff --git a/autobuild.xml b/autobuild.xml
index 754edabb8bf80333dbb7fd74741d0be78c4dc42e..e37eba5ec1db8f840aadb35cc48139d687765f50 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2528,9 +2528,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c5ab9d9d7482e48cd76f4bf391900a8c</string>
+              <string>6989053898b8e81e904e75553e378820</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/43369/385585/viewer_manager-2.0.531000-darwin64-531000.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77523/735051/viewer_manager-2.0.556340-darwin64-556340.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2540,9 +2540,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6b10d7407686d9e12e63576256581e3e</string>
+              <string>3446c1e54bb32542677caad0ec0d42ac</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/43370/385592/viewer_manager-2.0.531000-windows-531000.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77525/735058/viewer_manager-2.0.556340-windows-556340.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -2553,7 +2553,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.531000</string>
+        <string>2.0.556340</string>
       </map>
       <key>vlc-bin</key>
       <map>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 5a389e30cd71f7154b3870748bbaab48de120a2d..d0c9bce9126893446e5d7d8a4b25acacfdf59867 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -227,6 +227,7 @@ Ansariel Hiller
 	SL-13364
 	SL-13858
 	SL-13697
+	SL-3136
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
@@ -264,10 +265,10 @@ Benja Kepler
 Benjamin Bigdipper
 Beq Janus
 	BUG-227094
-Beth Walcher
-Beq Janus
 	SL-10288
 	SL-13583
+	SL-14766
+Beth Walcher
 Bezilon Kasei
 Biancaluce Robbiani
 	CT-225
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 5ba688c86496dffb8d9a5008dd56a0d72873e18d..a3f3e4bc66fc6c9001dd61bff472ef1281cb0355 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -56,10 +56,6 @@
 #include "stringize.h"
 #include "llexception.h"
 
-#if LL_WINDOWS
-#include <excpt.h>
-#endif
-
 // static
 LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
 {
@@ -253,29 +249,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
 
 #if LL_WINDOWS
 
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
-    if (code == STATUS_MSC_EXCEPTION)
-    {
-        // C++ exception, go on
-        return EXCEPTION_CONTINUE_SEARCH;
-    }
-    else
-    {
-        // handle it
-        return EXCEPTION_EXECUTE_HANDLER;
-    }
-}
-
 void LLCoros::winlevel(const callable_t& callable)
 {
     __try
     {
         callable();
     }
-    __except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
+    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
     {
         // convert to C++ styled exception
         // Note: it might be better to use _se_set_translator
diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp
index 5ce895868798336dc4dfa5ef8dea3ebdfbc2e0b7..b584b0ff8b53c2a4efb58e40f4d4aef210fb1466 100644
--- a/indra/llcommon/llexception.cpp
+++ b/indra/llcommon/llexception.cpp
@@ -24,11 +24,14 @@
 // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if
 // _Unwind_Backtrace is available without `_GNU_SOURCE`."
 #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED
+
 #if LL_WINDOWS
 // On Windows, header-only implementation causes macro collisions -- use
 // prebuilt library
 #define BOOST_STACKTRACE_LINK
+#include <excpt.h>
 #endif // LL_WINDOWS
+
 #include <boost/stacktrace.hpp>
 // other Linden headers
 #include "llerror.h"
@@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc)
     // Anyway, which of us is really going to examine more than 100 frames?
     exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100));
 }
+
+#if LL_WINDOWS
+
+// For windows SEH exception handling we sometimes need a filter that will
+// separate C++ exceptions from C SEH exceptions
+static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
+
+U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
+{
+    if (code == STATUS_MSC_EXCEPTION)
+    {
+        // C++ exception, go on
+        return EXCEPTION_CONTINUE_SEARCH;
+    }
+    else
+    {
+        // handle it
+        return EXCEPTION_EXECUTE_HANDLER;
+    }
+}
+
+#endif //LL_WINDOWS
diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h
index 422dd8810a3228ab6b2005e8a497f6fc52d36086..375bea4a5739577cfcc90097b855a3566a83434b 100644
--- a/indra/llcommon/llexception.h
+++ b/indra/llcommon/llexception.h
@@ -102,4 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str
      log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT)
 void log_unhandled_exception_(const char*, int, const char*, const std::string&);
 
+
+#if LL_WINDOWS
+
+// SEH exception filtering for use in __try __except
+// Separates C++ exceptions from C SEH exceptions
+// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&);
+U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop);
+
+#endif //LL_WINDOWS
+
 #endif /* ! defined(LL_LLEXCEPTION_H) */
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 3b9e68a623494035aca4ff58e3e0b551ec07fb54..301e86662d96472e1fda0566be49b9a8fe5a203c 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -50,6 +50,7 @@
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_float.hpp>
+#include "llfasttimer.h"
 
 using namespace llsd;
 
@@ -919,8 +920,12 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 	return *this;
 }
 
+static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats");
+
 LLSD LLMemoryInfo::loadStatsMap()
 {
+	LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS);
+
 	// This implementation is derived from stream() code (as of 2011-06-29).
 	Stats stats;
 
@@ -942,24 +947,11 @@ LLSD LLMemoryInfo::loadStatsMap()
 	stats.add("Total Virtual KB",   state.ullTotalVirtual/div);
 	stats.add("Avail Virtual KB",   state.ullAvailVirtual/div);
 
-	PERFORMANCE_INFORMATION perf;
-	perf.cb = sizeof(perf);
-	GetPerformanceInfo(&perf, sizeof(perf));
-
-	SIZE_T pagekb(perf.PageSize/1024);
-	stats.add("CommitTotal KB",     perf.CommitTotal * pagekb);
-	stats.add("CommitLimit KB",     perf.CommitLimit * pagekb);
-	stats.add("CommitPeak KB",      perf.CommitPeak * pagekb);
-	stats.add("PhysicalTotal KB",   perf.PhysicalTotal * pagekb);
-	stats.add("PhysicalAvail KB",   perf.PhysicalAvailable * pagekb);
-	stats.add("SystemCache KB",     perf.SystemCache * pagekb);
-	stats.add("KernelTotal KB",     perf.KernelTotal * pagekb);
-	stats.add("KernelPaged KB",     perf.KernelPaged * pagekb);
-	stats.add("KernelNonpaged KB",  perf.KernelNonpaged * pagekb);
-	stats.add("PageSize KB",        pagekb);
-	stats.add("HandleCount",        perf.HandleCount);
-	stats.add("ProcessCount",       perf.ProcessCount);
-	stats.add("ThreadCount",        perf.ThreadCount);
+	// SL-12122 - Call to GetPerformanceInfo() was removed here. Took
+	// on order of 10 ms, causing unacceptable frame time spike every
+	// second, and results were never used. If this is needed in the
+	// future, must find a way to avoid frame time impact (e.g. move
+	// to another thread, call much less often).
 
 	PROCESS_MEMORY_COUNTERS_EX pmem;
 	pmem.cb = sizeof(pmem);
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index fde6ed65e50368425662b3e46ca16e2490de3682..8fd6b16c0fed6a9b91d0c37f79086e429b5a0b4d 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -29,10 +29,13 @@
 #include "linden_common.h"
 #include "lluriparser.h"
 
+#if LL_DARWIN
+#include <signal.h>
+#include <setjmp.h>
+#endif
+
 LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)
 {
-	mState.uri = &mUri;
-
 	if (u.find("://") == std::string::npos)
 	{
 		mNormalizedUri = "http://";
@@ -51,7 +54,7 @@ LLUriParser::~LLUriParser()
 
 S32 LLUriParser::parse()
 {
-	mRes = uriParseUriA(&mState, mNormalizedUri.c_str());
+	mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL);
 	return mRes;
 }
 
@@ -158,31 +161,69 @@ void LLUriParser::extractParts()
 	}
 }
 
+#if LL_DARWIN
+typedef void(*sighandler_t)(int);
+jmp_buf return_to_normalize;
+void uri_signal_handler(int signal)
+{
+    // Apparently signal handler throwing an exception doesn't work.
+    // This is ugly and unsafe due to not unwinding content of uriparser library,
+    // but unless we have a way to catch this as NSexception, jump appears to be the only option.
+    longjmp(return_to_normalize, 1 /*setjmp will return this value*/);
+}
+#endif
+
 S32 LLUriParser::normalize()
 {
 	mNormalizedTmp = mTmpScheme;
 	if (!mRes)
 	{
-		mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
-
-		if (!mRes)
-		{
-			S32 chars_required;
-			mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
-
-			if (!mRes)
-			{
-				chars_required++;
-				std::vector<char> label_buf(chars_required);
-				mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
-
-				if (!mRes)
-				{
-					mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
-					mTmpScheme = false;
-				}
-			}
-		}
+#if LL_DARWIN
+        sighandler_t last_handler;
+        last_handler = signal(SIGILL, &uri_signal_handler);		// illegal instruction
+        if (setjmp(return_to_normalize))
+        {
+            // Issue: external library crashed via signal
+            // If you encountered this, please try to figure out what's wrong:
+            // 1. Verify that library's input is 'sane'
+            // 2. Check if we have an NSexception to work with (unlikely)
+            // 3. See if passing same string causes exception to repeat
+            //
+            // Crash happens at uriNormalizeSyntaxExA
+            // Warning!!! This does not properly unwind stack,
+            // if this can be handled by NSexception, it needs to be remade
+            llassert(0);
+
+            LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL;
+            signal(SIGILL, last_handler);
+            return 1;
+        }
+#endif
+
+        mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
+
+#if LL_DARWIN
+        signal(SIGILL, last_handler);
+#endif
+
+        if (!mRes)
+        {
+            S32 chars_required;
+            mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
+
+            if (!mRes)
+            {
+                chars_required++;
+                std::vector<char> label_buf(chars_required);
+                mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
+
+                if (!mRes)
+                {
+                    mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
+                    mTmpScheme = false;
+                }
+            }
+        }
 	}
 
 	if(mTmpScheme)
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index cfbf54f3c8592fb597a1c297988b67ff8d7ad96e..92626b90540232c3cc4d2e9d7ddef58fd6af0f6c 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -76,7 +76,6 @@ class LL_COMMON_API LLUriParser
 	std::string mFragment;
 	std::string mNormalizedUri;
 
-	UriParserStateA mState;
 	UriUriA mUri;
 
 	S32 mRes;
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index adebe851c4efac7d3f60d902539ac3ead4c203ce..7452138c196b1ecd958c3dd79abc7bbb9e794a18 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -255,7 +255,7 @@ class LLAssetStorage
 
     virtual void logAssetStorageInfo() = 0;
     
-	void checkForTimeouts();
+	virtual void checkForTimeouts();
 
 	void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
 									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype,
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 8579e6b0f63f4273b0b3382ae2d847ad1eaa9d15..fc81362f3356de8f0ff6ed2dfed68c50b058e018 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -144,10 +144,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
     }
 
     LLSD httpResults;
+    bool success = true;
 
     try
     {
-        bool success = true;
 
         LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", sHttpPolicy);
         LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url);
@@ -162,35 +162,47 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
         else
         {
             httpResults = results["http_result"];
-            success = httpResults["success"].asBoolean();
-            if (!success)
+            if (!httpResults.isMap())
             {
-                LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
-                    << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+                success = false;
+                LL_WARNS("AvNameCache") << " Invalid http_result returned from LLCoreHttpUtil::HttpCoroHandler." << LL_ENDL;
             }
-        }
-
-        if (!success)
-        {   // on any sort of failure add dummy records for any agent IDs 
-            // in this request that we do not have cached already
-            std::vector<LLUUID>::const_iterator it = agentIds.begin();
-            for ( ; it != agentIds.end(); ++it)
+            else
             {
-                const LLUUID& agent_id = *it;
-                LLAvatarNameCache::getInstance()->handleAgentError(agent_id);
+                success = httpResults["success"].asBoolean();
+                if (!success)
+                {
+                    LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+                        << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+                }
             }
-            return;
         }
 
-        LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
+        if (LLAvatarNameCache::instanceExists())
+        {
+            if (!success)
+            {   // on any sort of failure add dummy records for any agent IDs 
+                // in this request that we do not have cached already
+                std::vector<LLUUID>::const_iterator it = agentIds.begin();
+                for (; it != agentIds.end(); ++it)
+                {
+                    const LLUUID& agent_id = *it;
+                    LLAvatarNameCache::getInstance()->handleAgentError(agent_id);
+                }
+                return;
+            }
 
+            LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
+        }
     }
     catch (...)
     {
         LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
-                                          << "('" << url << "', " << agentIds.size()
-                                          << " http result: " << httpResults.asString()
-                                          << " Agent Ids)"));
+                                          << "('" << url << "', "
+                                          << agentIds.size() << "Agent Ids,"
+                                          << " http result: " << S32(success)
+                                          << " has response: " << S32(httpResults.size())
+                                          << ")"));
         throw;
     }
 }
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 35f82b3a2758efc8b804c03c6933ba50e68fdca6..a935a9cebcf7a7c634a6d7fcdabe916496a1b8ce 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -47,7 +47,7 @@ static const std::map<std::string, U32> DefaultPoolSizes{
 };
 
 static const U32 DEFAULT_POOL_SIZE = 5;
-static const U32 DEFAULT_QUEUE_SIZE = 4096;
+const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096;
 
 //=========================================================================
 class LLCoprocedurePool: private boost::noncopyable
@@ -194,7 +194,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd
     mPropertyDefineFn = updatefn;
 
     // workaround until we get mutex into initializePool
-    initializePool("VAssetStorage");
+    initializePool("AssetStorage");
     initializePool("Upload");
 }
 
@@ -292,7 +292,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
     mPoolSize(size),
     mActiveCoprocsCount(0),
     mPending(0),
-    mPendingCoprocs(boost::make_shared<CoprocQueue_t>(DEFAULT_QUEUE_SIZE)),
+    mPendingCoprocs(boost::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)),
     mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
     mCoroMapping()
 {
@@ -343,7 +343,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
         mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter));
     }
 
-    LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << DEFAULT_QUEUE_SIZE << LL_ENDL;
+    LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL;
 }
 
 LLCoprocedurePool::~LLCoprocedurePool() 
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 2c620efe5182cc91fd9101e06bad8b7ea2f66c75..723aafe288d0de8c19d0480f4325483045da4044 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -93,6 +93,9 @@ class LLCoprocedureManager final : public LLSingleton < LLCoprocedureManager >
 
     SettingQuery_t mPropertyQueryFn;
     SettingUpdate_t mPropertyDefineFn;
+
+public:
+    static const U32 DEFAULT_QUEUE_SIZE;
 };
 
 #endif
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index a219ac14501a9fee140e004bbbfb132ba6aca9d5..a1bfc4edd90979aee600125f7b3c3e8c0b885fff 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -28,6 +28,8 @@
 
 #include "llmaterial.h"
 
+#include "../llrender/llglheaders.h"
+
 /**
  * Materials cap parameters
  */
@@ -105,6 +107,8 @@ LLMaterial::LLMaterial()
     , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
     , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
     , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+    , mDiffuseFormatPrimary(GL_RGBA)
+    , mDiffuseBaked(false)
     , mAlphaMaskCutoff(0)
 {
 }
@@ -311,6 +315,20 @@ void LLMaterial::setEnvironmentIntensity(U8 intensity)
     mEnvironmentIntensity = intensity;
 }
 
+U8 LLMaterial::getDiffuseAlphaModeRender() const
+{
+    if (mDiffuseBaked
+        || mDiffuseFormatPrimary == GL_RGBA
+        || mDiffuseFormatPrimary == GL_ALPHA)
+    {
+        return mDiffuseAlphaMode;
+    }
+    else
+    {
+        return DIFFUSE_ALPHA_MODE_NONE;
+    }
+}
+
 U8 LLMaterial::getDiffuseAlphaMode() const
 {
     return mDiffuseAlphaMode;
@@ -321,6 +339,26 @@ void LLMaterial::setDiffuseAlphaMode(U8 alpha_mode)
     mDiffuseAlphaMode = alpha_mode;
 }
 
+U32 LLMaterial::getDiffuseFormatPrimary() const
+{
+    return mDiffuseFormatPrimary;
+}
+
+void LLMaterial::setDiffuseFormatPrimary(U32 format_primary)
+{
+    mDiffuseFormatPrimary = format_primary;
+}
+
+bool LLMaterial::getIsDiffuseBaked() const
+{
+    return mDiffuseBaked;
+}
+
+void LLMaterial::setDiffuseBaked(bool baked)
+{
+    mDiffuseBaked = baked;
+}
+
 U8 LLMaterial::getAlphaMaskCutoff() const
 {
     return mAlphaMaskCutoff;
@@ -437,7 +475,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)
     }
     else
     {
-        ret = getDiffuseAlphaMode();
+        ret = getDiffuseAlphaModeRender();
     }
 
     llassert(ret < SHADER_COUNT);
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index 83c86c81d559ebd550092642a7a3d2a17524445f..bf732c6fdb453766e942ac7a9be7345b115daff7 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -115,8 +115,17 @@ class LLMaterial final : public LLRefCount
     void        setSpecularLightExponent(U8 exponent);
     U8          getEnvironmentIntensity() const;
     void        setEnvironmentIntensity(U8 intensity);
+
+    // getDiffuseAlphaModeRender takes into account if image supports alpha
+    // and returns value apropriate for render
+    // getDiffuseAlphaMode() returns value as is
+    U8          getDiffuseAlphaModeRender() const;
     U8          getDiffuseAlphaMode() const;
     void        setDiffuseAlphaMode(U8 alpha_mode);
+    U32         getDiffuseFormatPrimary() const;
+    void        setDiffuseFormatPrimary(U32 format_primary);
+    bool        getIsDiffuseBaked() const;
+    void        setDiffuseBaked(bool baked);
     U8          getAlphaMaskCutoff() const;
     void        setAlphaMaskCutoff(U8 cutoff);
 
@@ -147,6 +156,8 @@ class LLMaterial final : public LLRefCount
     U8          mSpecularLightExponent;
     U8          mEnvironmentIntensity;
     U8          mDiffuseAlphaMode;
+    U32         mDiffuseFormatPrimary; // value from texture, LLGLenum, is not included in fromLLSD/asLLSD
+    bool        mDiffuseBaked; // is not included in fromLLSD/asLLSD
     U8          mAlphaMaskCutoff;
 };
 
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index b1ab2857186131e4ce78492f1eab9a7fb21ebe7d..13e83ea08424616ef820bb54b423d2a1ac926756 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -187,10 +187,32 @@ void LLCheckBoxCtrl::clear()
 
 void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	S32 label_top = mLabel->getRect().mTop;
-	mLabel->reshapeToFitText();
+    LLRect rect = getRect();
+    S32 delta_width = width - rect.getWidth();
+    S32 delta_height = height - rect.getHeight();
 
-	LLRect label_rect = mLabel->getRect();
+    if (delta_width || delta_height)
+    {
+        // adjust our rectangle
+        rect.mRight = getRect().mLeft + width;
+        rect.mTop = getRect().mBottom + height;
+        setRect(rect);
+    }
+
+    // reshapeToFitText reshapes label to minimal size according to last bounding box
+    // it will work fine in case of decrease of space, but if we get more space or text
+    // becomes longer, label will fail to grow so reinit label's dimentions.
+    
+    static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
+    LLRect label_rect = mLabel->getRect();
+    S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
+    label_rect.mRight = label_rect.mLeft + new_width;
+    mLabel->setRect(label_rect);
+
+	S32 label_top = label_rect.mTop;
+	mLabel->reshapeToFitText(TRUE);
+
+    label_rect = mLabel->getRect();
 	if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN)
 	{
 		// reshapeToFitText uses LLView::reshape() which always reshapes
@@ -210,6 +232,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 		llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),
 		llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));
 	mButton->setShape(btn_rect);
+
+    updateBoundingRect();
 }
 
 //virtual
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 2a0de80ad4ac44a66dea21d81f39e445700461a6..4484d3209a0db771551216b8a90413058bdd7a3f 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -204,6 +204,7 @@ class LLFolderViewModelItem : public LLRefCount, public LLTrace::MemTrackable<LL
 	virtual bool hasChildren() const = 0;
 	virtual void addChild(LLFolderViewModelItem* child) = 0;
 	virtual void removeChild(LLFolderViewModelItem* child) = 0;
+	virtual void clearChildren() = 0;
 
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
@@ -301,9 +302,8 @@ class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 	
 	virtual void clearChildren()
 	{
-		// As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects
-		// This is different and not equivalent to calling removeChild() on each child
-		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+		// We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest
+		std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); });
 		mChildren.clear();
 		dirtyDescendantsFilter();
 		dirtyFilter();
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index b238e0a3ceb2f765939a3db843f24619b079fd25..282305cb7dc95a83923c41a3879ca1b71ca7abc0 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -167,7 +167,7 @@ void LLLayoutPanel::setVisible( BOOL visible )
 
 void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ )
 {
-	if (width == getRect().getWidth() && height == getRect().getHeight()) return;
+	if (width == getRect().getWidth() && height == getRect().getHeight() && !LLView::sForceReshape) return;
 
 	if (!mIgnoreReshape && mAutoResize == false)
 	{
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 5aa14b2fbf665d90475e759728283b8b7c25b98a..0c3c09ed46812d26f9255248d57220c88924de77 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3276,7 +3276,7 @@ void hide_top_view( LLView* view )
 // x and y are the desired location for the popup, in the spawning_view's
 // coordinate frame, NOT necessarily the mouse location
 // static
-void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
+void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x, S32 mouse_y)
 {
 	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size
 	const S32 CURSOR_WIDTH = 12;
@@ -3307,12 +3307,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 		}
 	}
 
-	// Save click point for detecting cursor moves before mouse-up.
-	// Must be in local coords to compare with mouseUp events.
-	// If the mouse doesn't move, the menu will stay open ala the Mac.
-	// See also LLContextMenu::show()
-	S32 mouse_x, mouse_y;
-
 	// Resetting scrolling position
 	if (menu->isScrollable() && menu->isScrollPositionOnShowReset())
 	{
@@ -3323,7 +3317,18 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 	menu->needsArrange();
 	menu->arrangeAndClear();
 
-	LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+	if ((mouse_x == 0) || (mouse_y == 0))
+
+	{
+		// Save click point for detecting cursor moves before mouse-up.
+		// Must be in local coords to compare with mouseUp events.
+		// If the mouse doesn't move, the menu will stay open ala the Mac.
+		// See also LLContextMenu::show()
+
+		LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+	}
+	
+	
 	LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
 
 	const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect();
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index f9293d83cceca5b76f3e7a808083f54fee36276d..7413916617ad93336f3aeff5aec95e70a5462a83 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -519,7 +519,7 @@ class LLMenuGL
 	void createJumpKeys();
 
 	// Show popup at a specific location, in the spawn_view's coordinate frame
-	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y);
+	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x = 0, S32 mouse_y = 0);
 
 	// Whether to drop shadow menu bar 
 	void setDropShadowed( const BOOL shadowed );
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 1451eace3944b3aa91a6f8974ca9287add61c209..c25ffbb8ffcdea001293ec636ee71cc7dba287b7 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1284,7 +1284,7 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask)
 
 void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	if (width != getRect().getWidth() || height != getRect().getHeight())
+	if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape)
 	{
 		bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false;
 
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index f8a5a98cfa63c4821ac733e89965d72876b3718c..d4ea584f0d10e66d576e570e08044746d2a6c089 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -163,13 +163,13 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text
 }
 
 
-void LLTextBox::reshapeToFitText()
+void LLTextBox::reshapeToFitText(BOOL called_from_parent)
 {
 	reflow();
 
 	S32 width = getTextPixelWidth();
 	S32 height = getTextPixelHeight();
-	reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE );
+	reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent );
 }
 
 
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index dd7a3aff39af76c328191aa6d83ca015d5fb55e5..c0da52e8b57543697acdb7b804a5ecdcae85fc5f 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -60,7 +60,7 @@ class LLTextBox :
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
 	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL );
 
-	void			reshapeToFitText();
+	void			reshapeToFitText(BOOL called_from_parent = FALSE);
 
 	S32				getTextPixelWidth();
 	S32				getTextPixelHeight();
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 0e547dce7675edae5442a5ec4a99b588559ad092..7d08fdddcb9cef6a5bf204852164ec56381d5303 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1430,7 +1430,9 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
 			S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;
 			S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;
 			viewp->translate( delta_x, delta_y );
-			if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight())
+			if (child_rect.getWidth() != viewp->getRect().getWidth()
+                || child_rect.getHeight() != viewp->getRect().getHeight()
+                || sForceReshape)
 			{
 				viewp->reshape(child_rect.getWidth(), child_rect.getHeight());
 			}
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index d77997a928000b1a152f174268818d3d71022aef..30bc743e72fbf31b5efb889dd4995beaeecea8e0 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -263,6 +263,18 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList()
 #endif
 }
 
+// static
+std::vector<std::string> LLWindow::getDisplaysResolutionList()
+{
+#if LL_WINDOWS
+	return LLWindowWin32::getDisplaysResolutionList();
+#elif LL_DARWIN
+	return LLWindowMacOSX::getDisplaysResolutionList();
+#else
+	return std::vector<std::string>();
+#endif
+}
+
 #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
 #define UTF16_IS_LOW_SURROGATE(U)  ((U16)((U) - 0xDC00) < 0x0400)
 #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 290e3ab738b14dde25fd58befd4eb14bd6b62671..9eba7d62cb324b1046ba6cc0ebbe26e9a5fb2502 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -169,6 +169,8 @@ class LLWindow : public LLInstanceTracker<LLWindow>
 	// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
 	virtual F32 getSystemUISize() { return 1.0; }
 
+	static std::vector<std::string> getDisplaysResolutionList();
+
     // windows only DirectInput8 for joysticks
     virtual void* getDirectInput8() { return NULL; };
     virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 5f89bf92b0862a3f13385c8a9c51885de5912070..836fbcbae55c2ca2227e61cc355600a2f9384f38 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -40,6 +40,7 @@
 
 #include <OpenGL/OpenGL.h>
 #include <CoreServices/CoreServices.h>
+#include <CoreGraphics/CGDisplayConfiguration.h>
 
 extern BOOL gDebugWindowProc;
 
@@ -1864,6 +1865,35 @@ void LLWindowMacOSX::interruptLanguageTextInput()
 	commitCurrentPreedit(mGLView);
 }
 
+std::vector<std::string> LLWindowMacOSX::getDisplaysResolutionList()
+{
+	std::vector<std::string> resolution_list;
+	
+	CGDirectDisplayID display_ids[10];
+	uint32_t found_displays = 0;
+	CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays);
+	
+	if (kCGErrorSuccess != err)
+	{
+		LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL;
+		return std::vector<std::string>();
+	}
+	
+	for (uint32_t i = 0; i < found_displays; i++)
+	{
+		S32 monitor_width = CGDisplayPixelsWide(display_ids[i]);
+		S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]);
+		
+		std::ostringstream sstream;
+		sstream << monitor_width << "x" << monitor_height;;
+		std::string res = sstream.str();
+		
+		resolution_list.push_back(res);
+	}
+	
+	return resolution_list;
+}
+
 //static
 std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()
 {
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 31fd56dc4b893962bd31fd0e192631a1649d2fa5..32a6dcf79bbf844eb66225ab9ac5c99bcf040f6d 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -115,6 +115,8 @@ class LLWindowMacOSX : public LLWindow
 	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
 	/*virtual*/ F32 getSystemUISize();
 
+	static std::vector<std::string> getDisplaysResolutionList();
+
 	static std::vector<std::string> getDynamicFallbackFontList();
 
 	// Provide native key event data
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 0605a60407ff3d6a48e9abb2efbf4de780d8d7f3..ca75caf76f7f523100fc7e357004ca2227172f09 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -38,6 +38,7 @@
 
 // Linden library includes
 #include "llerror.h"
+#include "llexception.h"
 #include "llfasttimer.h"
 #include "llgl.h"
 #include "llstring.h"
@@ -82,7 +83,7 @@ void show_window_creation_error(const std::string& title)
 	LL_WARNS("Window") << title << LL_ENDL;
 }
 
-HGLRC SafeCreateContext(HDC hdc)
+HGLRC SafeCreateContext(HDC &hdc)
 {
 	__try 
 	{
@@ -94,6 +95,22 @@ HGLRC SafeCreateContext(HDC hdc)
 	}
 }
 
+GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+    __try
+    {
+        return ChoosePixelFormat(hdc, ppfd);
+    }
+    __except (EXCEPTION_EXECUTE_HANDLER)
+    {
+        // convert to C++ styled exception
+        // C exception don't allow classes, so it's a regular char array
+        char integer_string[32];
+        sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
+        throw std::exception(integer_string);
+    }
+}
+
 //static
 BOOL LLWindowWin32::sIsClassRegistered = FALSE;
 
@@ -365,6 +382,39 @@ LLWinImm::~LLWinImm()
 }
 
 
+class LLMonitorInfo
+{
+public:
+
+	std::vector<std::string> getResolutionsList() { return mResList; }
+
+	LLMonitorInfo()
+	{
+		EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this);
+	}
+
+private:
+
+	static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
+	{
+		int monitor_width = lprcMonitor->right - lprcMonitor->left;
+		int monitor_height = lprcMonitor->bottom - lprcMonitor->top;
+		
+		std::ostringstream sstream;
+		sstream << monitor_width << "x" << monitor_height;;
+		std::string res = sstream.str();
+
+		LLMonitorInfo* pThis = reinterpret_cast<LLMonitorInfo*>(pData);
+		pThis->mResList.push_back(res);
+
+		return TRUE;
+	}
+
+	std::vector<std::string> mResList;
+};
+
+static LLMonitorInfo sMonitorInfo;
+
 LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 							 const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
 							 S32 height, U32 flags, 
@@ -470,7 +520,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 	memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp));
 	memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp));
 	mCustomGammaSet = FALSE;
-	
+	mWindowHandle = NULL;
+
 	if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0))
 	{
 		mMouseVanish = TRUE;
@@ -1266,7 +1317,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
         << " Height: " << (window_rect.bottom - window_rect.top)
         << " Fullscreen: " << mFullscreen
         << LL_ENDL;
-    if (!destroy_window_handler(mWindowHandle))
+    if (mWindowHandle && !destroy_window_handler(mWindowHandle))
     {
         LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;
     }	
@@ -1325,13 +1376,26 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 
 	LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ;
 
-	if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
-	{
-		close();
-		OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
-			mCallbacks->translateString("MBError"), OSMB_OK);
-		return FALSE;
-	}
+    try
+    {
+        // Looks like ChoosePixelFormat can crash in case of faulty driver
+        if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd)))
+        {
+            LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL;
+            OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
+                mCallbacks->translateString("MBError"), OSMB_OK);
+            close();
+            return FALSE;
+        }
+    }
+    catch (...)
+    {
+        LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat");
+        OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
+            mCallbacks->translateString("MBError"), OSMB_OK);
+        close();
+        return FALSE;
+    }
 
 	LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ;
 
@@ -1599,7 +1663,6 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 				mhDC = nullptr;											// Zero The Device Context
 			}
 
-        // Destroy The Window
 			oldWND = mWindowHandle;
 		}
 
@@ -4389,6 +4452,12 @@ F32 LLWindowWin32::getSystemUISize()
 	return scale_value;
 }
 
+//static
+std::vector<std::string> LLWindowWin32::getDisplaysResolutionList()
+{ 
+	return sMonitorInfo.getResolutionsList();
+}
+
 //static
 std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
 {
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index b1f7dc0238e213760a719b45944952543c537701..fb059e559dba7db3c87ab02c3632d418d14a5cc2 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -155,6 +155,7 @@ class LLWindowWin32 : public LLWindow
 
 	LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
 
+	static std::vector<std::string> getDisplaysResolutionList();
 	static std::vector<std::string> getDynamicFallbackFontList();
 
     /*virtual*/ void* getDirectInput8();
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c0d6eb5be5ab992b353b9cff495eff40c177895e..00f92db2dfbb17aa8b77f1479a86461d6da79210 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -258,6 +258,7 @@ set(viewer_SOURCE_FILES
     llfloaterdeleteprefpreset.cpp
     llfloaterdestinations.cpp
     llfloaterdisplayname.cpp
+    llfloatereditenvironmentbase.cpp
     llfloatereditextdaycycle.cpp
     llfloaterenvironmentadjust.cpp
     llfloaterevent.cpp
@@ -926,6 +927,7 @@ set(viewer_HEADER_FILES
     llfloaterdeleteprefpreset.h
     llfloaterdestinations.h
     llfloaterdisplayname.h
+    llfloatereditenvironmentbase.h
     llfloatereditextdaycycle.h
     llfloaterenvironmentadjust.h
     llfloaterevent.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index a0b6fce83f47a718e061e75ce6493283983101a6..427dc381adc46644c4314d8086894f91f7ce7e16 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.18
+6.4.19
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 45326c94b8c50b02fabe70f8ee4be61a95227dd1..8edeb5af69ac1e979a39363f1052a9607ddda0a4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6302,7 +6302,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>http://map.secondlife.com.s3.amazonaws.com/</string>
+      <string>https://map.secondlife.com/</string>
     </map>
     <key>CurrentMapServerURL</key>
     <map>
@@ -15545,7 +15545,7 @@
         <key>Value</key>
             <real>1</real>
         </map>
-    <key>PoolSizeVAssetStorage</key>
+    <key>PoolSizeAssetStorage</key>
         <map>
         <key>Comment</key>
             <string>Coroutine Pool size for AssetStorage requests</string>
diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMP
index 09df573870e6aac8b5ea331fd143fd0ae4cd095e..dba26368031df55ba84d2c07a7e955c748e031d9 100644
Binary files a/indra/newview/installers/windows/install_icon.BMP and b/indra/newview/installers/windows/install_icon.BMP differ
diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMP
index 562b56676a9a87037f773cdd4ce2f2f1ba66b9d3..dba26368031df55ba84d2c07a7e955c748e031d9 100644
Binary files a/indra/newview/installers/windows/uninstall_icon.BMP and b/indra/newview/installers/windows/uninstall_icon.BMP differ
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index d88fed859dab2705da43e28a684bfbee4753c321..9d2e2ce18be2357a7288c942204db272f8c6b78c 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -135,6 +135,7 @@
 		// called again. Since it returned false, do not yet cancel
 		// frameTimer.
 		handleQuit();
+		[[NSApplication sharedApplication] stopModal];
 		return NSTerminateCancel;
 	} else {
 		// pumpMainLoop() returned true: it's done. Okay, done with frameTimer.
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6edaf3c7896bb5a23ea0e72502209f2d14725a1d..4a86dca1609143acb9cc52d1c1209b466370cb44 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1164,7 +1164,16 @@ bool LLAppViewer::init()
 	// add LEAP mode command-line argument to whichever of these we selected
 	updater.args.add("leap");
 	// UpdaterServiceSettings
-	updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+    if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+    {
+        // Befor first login, treat this as 'manual' updates,
+        // updater won't install anything, but required updates
+        updater.args.add("0");
+    }
+    else
+    {
+        updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+    }
 	// channel
 	updater.args.add(LLVersionInfo::instance().getChannel());
 	// testok
@@ -1640,6 +1649,7 @@ bool LLAppViewer::doFrame()
 		}
 
 		delete gServicePump;
+		gServicePump = NULL;
 
 		destroyMainloopTimeout();
 
@@ -1696,7 +1706,11 @@ bool LLAppViewer::cleanup()
 	//dump scene loading monitor results
 	if (LLSceneMonitor::instanceExists())
 	{
-		LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+		if (!isSecondInstance())
+		{
+			LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+		}
+		LLSceneMonitor::deleteSingleton();
 	}
 
 	// There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
@@ -3519,6 +3533,12 @@ void LLAppViewer::writeSystemInfo()
 	gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
     gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
 
+	std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
+	for (auto res_iter : resolutions)
+	{
+		gDebugInfo["DisplayInfo"].append(res_iter);
+	}
+
 	writeDebugInfo(); // Save out debug_info.log early, in case of crash.
 }
 
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index 1005ca95295451ae9a5eae718d517762c495ae85..88e4db36724c54e803e2db3e4ff148b99243fcec 100644
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -309,6 +309,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
         {
             if (isAgentAvatarValid() &&
                 gAgentAvatarp->isWearingAttachment(*it) &&
+                !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF!
                 !LLAppearanceMgr::instance().isLinkedInCOF(*it))
             {
                 LLUUID item_id = *it;
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 8861f4720577d80e80a01bbf41af488e87e13f2b..ad9f168f0f4aaf7e7a60513aa1d9d2b4c54c35f4 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -397,6 +397,24 @@ void LLConversationLog::deleteBackupLogs()
 	}
 }
 
+void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name)
+{
+    conversations_vec_t::iterator conv_it = mConversations.begin();
+    for (; conv_it != mConversations.end(); ++conv_it)
+    {
+        if (conv_it->getSessionID() == session_id)
+        {
+            if (conv_it->getHistoryFileName() != expected_filename)
+            {
+                LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename);
+                conv_it->updateHistoryFileName(expected_filename);
+                conv_it->setConversationName(new_session_name);
+            }
+            break;
+        }
+    }
+}
+
 bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
 {
 
@@ -517,7 +535,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	}
 	bool purge_required = false;
 
-	char buffer[MAX_STRING];
+	static constexpr int UTF_BUFFER{ 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare
+
+	char buffer[UTF_BUFFER];
 	char conv_name_buffer[MAX_STRING];
 	char part_id_buffer[MAX_STRING];
 	char conv_id_buffer[MAX_STRING];
@@ -528,11 +548,14 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	// before CHUI-348 it was a flag of conversation voice state
 	int prereserved_unused;
 
-	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+	memset(buffer, '\0', UTF_BUFFER);
+	while (!feof(fp) && fgets(buffer, UTF_BUFFER, fp))
 	{
-		conv_name_buffer[0] = '\0';
-		part_id_buffer[0]	= '\0';
-		conv_id_buffer[0]	= '\0';
+        // force blank for added safety
+        memset(conv_name_buffer, '\0', MAX_STRING);
+        memset(part_id_buffer, '\0', MAX_STRING);
+        memset(conv_id_buffer, '\0', MAX_STRING);
+        memset(history_file_name, '\0', MAX_STRING);
 
 		sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
@@ -569,6 +592,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		}
 
 		mConversations.push_back(conversation);
+		memset(buffer, '\0', UTF_BUFFER);
 	}
 	fclose(fp);
 
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 68b45de6ab0e08b472fbc25cb53f417728c0d120..1bb54456064d5e395aac8f9b567f6949b71f6b0f 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -59,7 +59,7 @@ class LLConversation
 						getTime()				const	{ return mTime; }
 	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
 
-	void setConversationName(std::string conv_name) { mConversationName = conv_name; }
+	void setConversationName(const std::string &conv_name) { mConversationName = conv_name; }
 	void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
 	bool isOlderThan(U32Days days) const;
 
@@ -68,6 +68,8 @@ class LLConversation
 	 */
 	void updateTimestamp();
 
+    void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; }
+
 	/*
 	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
 	 */
@@ -137,6 +139,8 @@ class LLConversationLog final : public LLSingleton<LLConversationLog>, LLIMSessi
 	 * public method which is called on viewer exit to save conversation log
 	 */
 	void cache();
+    // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't
+	void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name);
 	bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
 	void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
 	void deleteBackupLogs();
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index b7927ea05b6f0211e21cb790a8d06d6b81a4a32e..9bfb7878f3092914bd7f5c97ba33b940e8d05d57 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -350,11 +350,36 @@ void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
 
 void LLConversationItemSession::clearParticipants()
 {
+    // clearParticipants function potentially is malfunctioning since it only cleans children of models,
+    // it does nothing to views that own those models (listeners)
+    // probably needs to post some kind of 'remove all participants' event
 	clearChildren();
 	mIsLoaded = false;
 	mNeedsRefresh = true;
 }
 
+
+void LLConversationItemSession::clearAndDeparentModels()
+{
+    std::for_each(mChildren.begin(), mChildren.end(),
+        [](LLFolderViewModelItem* c)
+        {
+            if (c->getNumRefs() == 0)
+            {
+                // LLConversationItemParticipant can be created but not assigned to any view,
+                // it was waiting for an "add_participant" event to be processed
+                delete c;
+            }
+            else
+            {
+                // Model is still assigned to some view/widget
+                c->setParent(NULL);
+            }
+        }
+    );
+    mChildren.clear();
+}
+
 LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
 {
 	// This is *not* a general tree parsing algorithm. It assumes that a session contains only 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index c9e85d3602f7f79894070b6c004050511359067e..239d12876f9557f300684f21a5a4fc7d093ecfc2 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -165,6 +165,7 @@ class LLConversationItemSession : public LLConversationItem
 	void removeParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(const LLUUID& participant_id);
 	void clearParticipants();
+	void clearAndDeparentModels(); // will delete unowned models and deparent owned ones
 	LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
 
 	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index a3342c66afdfdb671ec1229b2d2a283e0d753ac3..163fa42e3fa6bf22cc8ce518d9db15ab0da73401 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -31,6 +31,7 @@
 
 #include <boost/bind.hpp>
 #include "llagentdata.h"
+#include "llavataractions.h"
 #include "llconversationmodel.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimnearbychat.h"
@@ -103,6 +104,56 @@ LLConversationViewSession::~LLConversationViewSession()
 	mFlashTimer->unset();
 }
 
+void LLConversationViewSession::destroyView()
+{
+    // Chat can create and parent models(listeners) to session's model before creating
+    // coresponding views, such participant's models normally will wait for idle cycles
+    // but since we are deleting session and won't be processing any more events, make
+    // sure unowned LLConversationItemParticipant models are removed as well.
+
+    LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
+
+    // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent
+    // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant)
+    if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        // Destroy existing views
+        while (!mItems.empty())
+        {
+            LLFolderViewItem *itemp = mItems.back();
+            mItems.pop_back();
+
+            LLFolderViewModelItem* item_vmi = itemp->getViewModelItem();
+            if (item_vmi) // supposed to exist
+            {
+                // unparent to remove from child list
+                vmi->removeChild(item_vmi);
+            }
+            itemp->destroyView();
+        }
+
+        // Not needed in scope of sessions, but just in case
+        while (!mFolders.empty())
+        {
+            LLFolderViewFolder *folderp = mFolders.back();
+            mFolders.pop_back();
+
+            LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem();
+            if (folder_vmi)
+            {
+                vmi->removeChild(folder_vmi);
+            }
+            folderp->destroyView();
+        }
+
+        // Now everything that is left in model(listener) is not owned by views,
+        // only by sessions, deparent so it won't point to soon to be dead model
+        vmi->clearAndDeparentModels();
+    }
+
+    LLFolderViewFolder::destroyView();
+}
+
 void LLConversationViewSession::setFlashState(bool flash_state)
 {
 	if (flash_state && !mFlashStateOn)
@@ -429,8 +480,13 @@ void LLConversationViewSession::refresh()
 	vmi->resetRefresh();
 
 	if (mSessionTitle)
-	{
-		mSessionTitle->setText(vmi->getDisplayName());
+	{		
+		if (!highlightFriendTitle(vmi))
+		{
+			LLStyle::Params title_style;
+			title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
+			mSessionTitle->setText(vmi->getDisplayName(), title_style);
+		}
 	}
 
 	// Update all speaking indicators
@@ -475,6 +531,22 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 	}
 }
 
+bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi)
+{
+	if(vmi->getType() == LLConversationItem::CONV_PARTICIPANT || vmi->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+	{
+		LLIMModel::LLIMSession* session=  LLIMModel::instance().findIMSession(vmi->getUUID());
+		if (session && LLAvatarActions::isFriend(session->mOtherParticipantID))
+		{
+			LLStyle::Params title_style;
+			title_style.color = LLUIColorTable::instance().getColor("ConversationFriendColor");
+			mSessionTitle->setText(vmi->getDisplayName(), title_style);
+			return true;
+		}
+	}
+	return false;
+}
+
 //
 // Implementation of conversations list participant (avatar) widgets
 //
@@ -575,7 +647,14 @@ void LLConversationViewParticipant::draw()
 	}
 	else
 	{
-		color = mIsSelected ? sHighlightFgColor : sFgColor;
+		if (LLAvatarActions::isFriend(mUUID))
+		{
+			color = LLUIColorTable::instance().getColor("ConversationFriendColor");
+		}
+		else
+		{
+			color = mIsSelected ? sHighlightFgColor : sFgColor;
+		}
 	}
 
 	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index f12e967df740324b72958560238fcd6032487fa0..b1c035c5606e67bd1eafbb2a6f175233ce39bc03 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -36,6 +36,7 @@
 class LLTextBox;
 class LLFloater;
 class LLFloaterIMContainer;
+class LLConversationItem;
 class LLConversationViewSession;
 class LLConversationViewParticipant;
 
@@ -66,6 +67,8 @@ class LLConversationViewSession : public LLFolderViewFolder
 public:
 	virtual ~LLConversationViewSession();
 
+	/*virtual*/ void destroyView();
+
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
@@ -93,6 +96,8 @@ class LLConversationViewSession : public LLFolderViewFolder
 	LLFloater* getSessionFloater();
 	bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; }
 
+	bool highlightFriendTitle(LLConversationItem* vmi);
+
 private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 5c8289b584e2ca5a71ccab87d9bc55d188db0a7c..f2329facefb23e6a5efe7dc7d0ea107148601be6 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -2074,7 +2074,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
             if (mat)
             {                
-                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode()))
+                switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaModeRender()))
                 {
                     case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
                     {
@@ -2221,7 +2221,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
 				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
 
-				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+				if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 				{
                     F32 cutoff = mat->getAlphaMaskCutoff()/255.f;
 					sVertexProgram->setMinimumAlpha(cutoff);
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 2fdde73749e2ac28ddbfcdb169e49cf46efbaade..598078e90dcf414a9561a5aac06e5c880f9d12d6 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -1187,7 +1187,7 @@ bool LLFace::canRenderAsMask()
 	}
 	
 	LLMaterial* mat = te->getMaterialParams();
-	if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+	if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
 	{
 		return false;
 	}
@@ -1369,7 +1369,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 			}
 			else
 			{
-				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+				if (!mat || mat->getDiffuseAlphaModeRender() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 				{
 					shiny_in_alpha = true;
 				}
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 632aef62b0aef2ca4930f5601f51c18b248eccb2..02d1f52aef493b8532f868588577a157b42382e7 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -384,6 +384,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 	mUpdateDropDownItems(true),
 	mRestoreOverflowMenu(false),
 	mGetPrevItems(true),
+	mMouseX(0),
+	mMouseY(0),
 	mItemsChangedTimer()
 {
 	// Register callback for menus with current registrar (will be parent panel's registrar)
@@ -399,7 +401,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 	//make chevron button                                                                                                                               
 	LLTextBox::Params more_button_params(p.more_button);
 	mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params);
-	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
+	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));
 	addChild(mMoreTextBox);
 
 	mDropDownItemsCount = 0;
@@ -975,6 +977,12 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
 	return TRUE;
 }
 
+void LLFavoritesBarCtrl::onMoreTextBoxClicked()
+{
+	LLUI::getInstance()->getMousePositionScreen(&mMouseX, &mMouseY);
+	showDropDownMenu();
+}
+
 void LLFavoritesBarCtrl::showDropDownMenu()
 {
 	if (mOverflowMenuHandle.isDead())
@@ -1130,7 +1138,7 @@ void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu)
 		}
 	}
 
-	LLMenuGL::showPopup(this, menu, menu_x, menu_y);
+	LLMenuGL::showPopup(this, menu, menu_x, menu_y, mMouseX, mMouseY);
 }
 
 void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index f204d26064c7c963b76da60cf5936fe2991acdde..201bd27c4f49713c3c95fc96e87053f0027a2262 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -96,6 +96,8 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 	
 	void showDropDownMenu();
 
+	void onMoreTextBoxClicked();
+
 	LLHandle<LLView> mOverflowMenuHandle;
 	LLHandle<LLView> mContextMenuHandle;
 
@@ -163,6 +165,9 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 
 	BOOL mTabsHighlightEnabled;
 
+	S32 mMouseX;
+	S32 mMouseY;
+
 	boost::signals2::connection mEndDragConnection;
 };
 
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 9cf113fcf7563a98f7eb17bf0f42a6cb082fbfdc..87761cbd4485e27f3aea170c9236427cc2d6cd33 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -379,22 +379,6 @@ F32 gpu_benchmark();
 
 #if LL_WINDOWS
 
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
-    if (code == STATUS_MSC_EXCEPTION)
-    {
-        // C++ exception, go on
-        return EXCEPTION_CONTINUE_SEARCH;
-    }
-    else
-    {
-        // handle it
-        return EXCEPTION_EXECUTE_HANDLER;
-    }
-}
-
 F32 logExceptionBenchmark()
 {
     // Todo: make a wrapper/class for SEH exceptions
@@ -403,7 +387,7 @@ F32 logExceptionBenchmark()
     {
         gbps = gpu_benchmark();
     }
-    __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation()))
+    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
     {
         // convert to C++ styled exception
         char integer_string[32];
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index e530eb4bbff473f82ec65593a11c2196b10eb346..8ca1a7f0295f512fac5c912288dd14a5d878b353 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -49,7 +49,8 @@
 #include "lltrans.h"
 
 LLFloaterBuy::LLFloaterBuy(const LLSD& key)
-:	LLFloater(key)
+:	LLFloater(key),
+	mSelectionUpdateSlot()
 {
 }
 
@@ -182,12 +183,19 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
 	floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
 	floater->getChild<LLUICtrl>("buy_name_text")->setTextArg("[NAME]", owner_name);
 
+	floater->showViews(true);
+
 	// Must do this after the floater is created, because
 	// sometimes the inventory is already there and 
 	// the callback is called immediately.
 	LLViewerObject* obj = selection->getFirstRootObject();
 	floater->registerVOInventoryListener(obj,NULL);
 	floater->requestVOInventory();
+
+	if (!floater->mSelectionUpdateSlot.connected())
+	{
+		floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater));
+	}
 }
 
 void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
@@ -283,6 +291,30 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
 	removeVOInventoryListener();
 }
 
+void LLFloaterBuy::onSelectionChanged()
+{
+	
+	if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0)
+	{
+		removeVOInventoryListener();
+		closeFloater();
+	}
+	else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1)
+	{
+		removeVOInventoryListener();
+		showViews(false);
+		reset();
+		setTitle(getString("mupliple_selected"));
+	}
+}
+
+void LLFloaterBuy::showViews(bool show)
+{
+	getChild<LLUICtrl>("buy_btn")->setEnabled(show);
+	getChild<LLUICtrl>("buy_text")->setVisible(show);
+	getChild<LLUICtrl>("buy_name_text")->setVisible(show);
+}
+
 void LLFloaterBuy::onClickBuy()
 {
 	// Put the items where we put new folders.
@@ -306,5 +338,10 @@ void LLFloaterBuy::onClickCancel()
 // virtual
 void LLFloaterBuy::onClose(bool app_quitting)
 {
+	if (mSelectionUpdateSlot.connected())
+	{
+		mSelectionUpdateSlot.disconnect();
+	}
+
 	mObjectSelection.clear();
 }
diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h
index 5f0f9d1cff5685826de41334d876dd0c5100a060..22e3beecdbc62abb642dd1f02012b6690b2e3bcb 100644
--- a/indra/newview/llfloaterbuy.h
+++ b/indra/newview/llfloaterbuy.h
@@ -63,12 +63,17 @@ class LLFloaterBuy final
 								 S32 serial_num,
 								 void* data);
 
+	void onSelectionChanged();
+	void showViews(bool show);
+
 	void onClickBuy();
 	void onClickCancel();
 
 private:
 	LLSafeHandle<LLObjectSelection>	mObjectSelection;
 	LLSaleInfo mSaleInfo;
+
+	boost::signals2::connection mSelectionUpdateSlot;
 };
 
 #endif
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index ddb7b35404a58039bfb8d8ea74776d2472b5a0ce..a838537ed08772b4f63800ed5c34384508dc43bf 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -460,6 +460,7 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
 
 	switch (mode)
 	{
+	case CAMERA_CTRL_MODE_PRESETS:
 	case CAMERA_CTRL_MODE_PAN:
 		sFreeCamera = false;
 		clear_camera_tool();
@@ -470,13 +471,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
 		activate_camera_tool();
 		break;
 
-	case CAMERA_CTRL_MODE_PRESETS:
-		if(sFreeCamera)
-		{
-			switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
-		}
-		break;
-
 	default:
 		//normally we won't occur here
 		llassert_always(FALSE);
@@ -531,7 +525,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param)
 		{
 			camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
 			camera_floater->updateItemsSelection();
-			camera_floater->fromFreeToPresets();
 		}
 	}
 	else
@@ -596,15 +589,7 @@ void LLFloaterCamera::switchToPreset(const std::string& name)
 	if (camera_floater)
 	{
 		camera_floater->updateItemsSelection();
-		camera_floater->fromFreeToPresets();
-	}
-}
-
-void LLFloaterCamera::fromFreeToPresets()
-{
-	if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS)
-	{
-		switchMode(CAMERA_CTRL_MODE_PRESETS);
+		camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS);
 	}
 }
 
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 4fcbe63736bffc62f9c6f3c86f69fa7348436609..f46487408f657642a03669e2f218d0bfddd0e63d 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -69,10 +69,6 @@ class LLFloaterCamera final : public LLFloater
 	/*switch to one of the camera presets (front, rear, side)*/
 	static void switchToPreset(const std::string& name);
 
-	/* move to CAMERA_CTRL_MODE_PRESETS from CAMERA_CTRL_MODE_FREE_CAMERA if we are on presets panel and
-	   are not in free camera mode*/
-	void fromFreeToPresets();
-
 	virtual void onOpen(const LLSD& key);
 	virtual void onClose(bool app_quitting);
 
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e888144b6aa104f5a5cd0ebebd02d8f1a3204d0e
--- /dev/null
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -0,0 +1,479 @@
+/** 
+ * @file llfloatereditenvironmentbase.cpp
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatereditenvironmentbase.h"
+
+#include <boost/make_shared.hpp>
+
+// libs
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llfilepicker.h"
+#include "llsettingspicker.h"
+#include "llviewerparcelmgr.h"
+
+// newview
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+
+#include "llenvironment.h"
+#include "llagent.h"
+#include "llparcel.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+
+namespace
+{
+    const std::string ACTION_APPLY_LOCAL("apply_local");
+    const std::string ACTION_APPLY_PARCEL("apply_parcel");
+    const std::string ACTION_APPLY_REGION("apply_region");
+}
+
+//=========================================================================
+const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id");
+
+
+//=========================================================================
+
+class LLFixedSettingCopiedCallback : public LLInventoryCallback
+{
+public:
+    LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+    virtual void fire(const LLUUID& inv_item_id)
+    {
+        if (!mHandle.isDead())
+        {
+            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+            if (item)
+            {
+                LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get();
+                floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+            }
+        }
+    }
+
+private:
+    LLHandle<LLFloater> mHandle;
+};
+
+//=========================================================================
+LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) :
+    LLFloater(key),
+    mInventoryId(),
+    mInventoryItem(nullptr),
+    mIsDirty(false),
+    mCanCopy(false),
+    mCanMod(false),
+    mCanTrans(false),
+    mCanSave(false)
+{
+}
+
+LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase()
+{
+}
+
+void LLFloaterEditEnvironmentBase::onFocusReceived()
+{
+    if (isInVisibleChain())
+    {
+        updateEditEnvironment();
+        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onFocusLost()
+{
+}
+
+void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans)
+{
+    if (inventoryId.isNull())
+    {
+        mInventoryItem = nullptr;
+        mInventoryId.setNull();
+        mCanMod = true;
+        mCanCopy = true;
+        mCanTrans = true;
+        return;
+    }
+
+    mInventoryId = inventoryId;
+    LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
+    mInventoryItem = gInventory.getItem(mInventoryId);
+
+    if (!mInventoryItem)
+    {
+        LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
+        LLNotificationsUtil::add("CantFindInvItem");
+        closeFloater();
+
+        mInventoryId.setNull();
+        mInventoryItem = nullptr;
+        return;
+    }
+
+    if (mInventoryItem->getAssetUUID().isNull())
+    {
+        LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
+        LLNotificationsUtil::add("UnableEditItem");
+        closeFloater();
+
+        mInventoryId.setNull();
+        mInventoryItem = nullptr;
+        return;
+    }
+
+    mCanSave = true;
+    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
+    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
+    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+    mExpectingAssetId = mInventoryItem->getAssetUUID();
+    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
+        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+
+void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb)
+{
+    if (isDirty())
+    {
+        LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType())
+            ("NAME", getEditSettings()->getName()));
+
+        // create and show confirmation textbox
+        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
+            [cb](const LLSD&notif, const LLSD&resp)
+            {
+                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+                if (opt == 0)
+                    cb();
+            });
+    }
+    else if (cb)
+    {
+        cb();
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+    if (asset_id != mExpectingAssetId)
+    {
+        LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL;
+        return;
+    }
+    mExpectingAssetId.setNull();
+    clearDirtyFlag();
+
+    if (!settings || status)
+    {
+        LLSD args;
+        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
+        LLNotificationsUtil::add("FailedToFindSettings", args);
+        closeFloater();
+        return;
+    }
+
+    if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
+    {
+        mCanSave = false;
+        mCanCopy = false;
+        mCanMod = false;
+        mCanTrans = false;
+    }
+    else
+    {
+        if (mInventoryItem)
+            settings->setName(mInventoryItem->getName());
+
+        if (mCanCopy)
+            settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
+        else
+            settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
+
+        if (mCanMod)
+            settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
+        else
+            settings->setFlag(LLSettingsBase::FLAG_NOMOD);
+
+        if (mCanTrans)
+            settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
+        else
+            settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
+    }
+
+    setEditSettingsAndUpdate(settings);
+}
+
+void LLFloaterEditEnvironmentBase::onButtonImport()
+{
+    checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); });
+}
+
+void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    if (0 == option)
+    {
+        std::string settings_name = response["message"].asString();
+
+        LLInventoryObject::correctInventoryName(settings_name);
+        if (settings_name.empty())
+        {
+            // Ideally notification should disable 'OK' button if name won't fit our requirements,
+            // for now either display notification, or use some default name
+            settings_name = "Unnamed";
+        }
+
+        if (mCanMod)
+        {
+            doApplyCreateNewInventory(settings_name, settings);
+        }
+        else if (mInventoryItem)
+        {
+            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+            LLUUID parent_id = mInventoryItem->getParentUUID();
+            if (marketplacelistings_id == parent_id)
+            {
+                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+            }
+
+            LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle());
+            copy_inventory_item(
+                gAgent.getID(),
+                mInventoryItem->getPermissions().getOwner(),
+                mInventoryItem->getUUID(),
+                parent_id,
+                settings_name,
+                cb);
+        }
+        else
+        {
+            LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL;
+        }
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting)
+{
+    if (!app_quitting)
+        checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
+    else
+        closeFloater();
+}
+
+void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings)
+{
+    if (mInventoryItem)
+    {
+        LLUUID parent_id = mInventoryItem->getParentUUID();
+        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
+        LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+    }
+    else
+    {
+        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+        // This method knows what sort of settings object to create.
+        LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name,
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+    }
+}
+
+void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings)
+{
+    LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL;
+    if (mInventoryId.isNull())
+    {
+        LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+    }
+    else
+    {
+        LLSettingsVOBase::updateInventoryItem(settings, mInventoryId,
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
+    }
+}
+
+void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings)
+{
+    U32 flags(0);
+
+    if (mInventoryItem)
+    {
+        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+            flags |= LLSettingsBase::FLAG_NOMOD;
+        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+            flags |= LLSettingsBase::FLAG_NOTRANS;
+    }
+
+    flags |= settings->getFlags();
+    settings->setFlag(flags);
+
+    if (where == ACTION_APPLY_LOCAL)
+    {
+        settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
+        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings);
+    }
+    else if (where == ACTION_APPLY_PARCEL)
+    {
+        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+
+        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
+        {
+            LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL;
+            LLNotificationsUtil::add("WLParcelApplyFail");
+            return;
+        }
+
+        if (mInventoryItem && !isDirty())
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+        }
+        else if (settings->getSettingsType() == "sky")
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "water")
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "day")
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsDay>(settings), -1, -1);
+        }
+    }
+    else if (where == ACTION_APPLY_REGION)
+    {
+        if (mInventoryItem && !isDirty())
+        {
+            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+        }
+        else if (settings->getSettingsType() == "sky")
+        {
+            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "water")
+        {
+            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "day")
+        {
+            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsDay>(settings), -1, -1);
+        }
+    }
+    else
+    {
+        LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL;
+        return;
+    }
+
+}
+
+void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting)
+{
+    LLFloater* floaterp = mInventoryFloater.get();
+
+    if (floaterp)
+    {
+        floaterp->closeFloater(quitting);
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+    LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+    if (inventory_id.isNull() || !results["success"].asBoolean())
+    {
+        LLNotificationsUtil::add("CantCreateInventory");
+        return;
+    }
+    onInventoryCreated(asset_id, inventory_id);
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
+    bool can_trans = true;
+    if (mInventoryItem)
+    {
+        LLPermissions perms = mInventoryItem->getPermissions();
+
+        LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+        if (created_item)
+        {
+            can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+            created_item->setPermissions(perms);
+            created_item->updateServer(false);
+        }
+    }
+
+    clearDirtyFlag();
+    setFocus(TRUE);                 // Call back the focus...
+    loadInventoryItem(inventory_id, can_trans);
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+    LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+    clearDirtyFlag();
+    if (inventory_id != mInventoryId)
+    {
+        loadInventoryItem(inventory_id);
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value)
+{
+    if (value)
+        setDirtyFlag();
+}
+
+//-------------------------------------------------------------------------
+bool LLFloaterEditEnvironmentBase::canUseInventory() const
+{
+    return LLEnvironment::instance().isInventoryEnabled();
+}
+
+bool LLFloaterEditEnvironmentBase::canApplyRegion() const
+{
+    return gAgent.canManageEstate();
+}
+
+bool LLFloaterEditEnvironmentBase::canApplyParcel() const
+{
+    return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
+}
+
+//=========================================================================
diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c7cf5bdcd7d1a3e524e2ac59d37297ba249faf7
--- /dev/null
+++ b/indra/newview/llfloatereditenvironmentbase.h
@@ -0,0 +1,148 @@
+/** 
+ * @file llfloatereditenvironmentbase.h
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATEREDITENVIRONMENTBASE_H
+#define LL_FLOATEREDITENVIRONMENTBASE_H
+
+#include "llfloater.h"
+#include "llsettingsbase.h"
+#include "llflyoutcombobtn.h"
+#include "llinventory.h"
+
+#include "boost/signals2.hpp"
+
+class LLTabContainer;
+class LLButton;
+class LLLineEditor;
+class LLFloaterSettingsPicker;
+class LLFixedSettingCopiedCallback;
+
+class LLFloaterEditEnvironmentBase : public LLFloater
+{
+    LOG_CLASS(LLFloaterEditEnvironmentBase);
+
+    friend class LLFixedSettingCopiedCallback;
+
+public:
+    static const std::string    KEY_INVENTORY_ID;
+
+                            LLFloaterEditEnvironmentBase(const LLSD &key);
+                            ~LLFloaterEditEnvironmentBase();
+
+    virtual void            onFocusReceived()           override;
+    virtual void            onFocusLost()               override;
+    
+    virtual LLSettingsBase::ptr_t   getEditSettings()   const = 0;
+
+    virtual BOOL            isDirty() const override            { return getIsDirty(); }
+
+protected:
+    typedef std::function<void()> on_confirm_fn;
+
+    virtual void            setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) = 0;
+    virtual void            updateEditEnvironment() = 0;
+
+    virtual LLFloaterSettingsPicker *getSettingsPicker() = 0;
+
+    void                    loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true);
+
+    void                    checkAndConfirmSettingsLoss(on_confirm_fn cb);
+
+    virtual void            doImportFromDisk() = 0;
+    virtual void            doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings);
+    virtual void            doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings);
+    virtual void            doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings);
+    void                    doCloseInventoryFloater(bool quitting = false);
+
+    bool                    canUseInventory() const;
+    bool                    canApplyRegion() const;
+    bool                    canApplyParcel() const;
+
+    LLUUID                  mInventoryId;
+    LLInventoryItem *       mInventoryItem;
+    LLHandle<LLFloater>     mInventoryFloater;
+    bool                    mCanCopy;
+    bool                    mCanMod;
+    bool                    mCanTrans;
+    bool                    mCanSave;
+
+    bool                    mIsDirty;
+
+    void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
+    void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+    void                    onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+    bool                    getIsDirty() const  { return mIsDirty; }
+    void                    setDirtyFlag()      { mIsDirty = true; }
+    virtual void            clearDirtyFlag() = 0;
+
+    void                    onPanelDirtyFlagChanged(bool);
+
+    virtual void            onClickCloseBtn(bool app_quitting = false) override;
+    void                    onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings);
+    void                    onButtonImport();
+
+    void                    onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
+
+private:
+    LLUUID                  mExpectingAssetId; // for asset load confirmation
+};
+
+class LLSettingsEditPanel : public LLPanel
+{
+public:
+    virtual void setSettings(const LLSettingsBase::ptr_t &) = 0;
+
+    typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg;
+    typedef boost::signals2::connection connection_t;
+
+    inline bool         getIsDirty() const      { return mIsDirty; }
+    inline void         setIsDirty()            { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
+    inline void         clearIsDirty()          { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
+
+    inline bool        getCanChangeSettings() const    { return mCanEdit; }
+    inline void        setCanChangeSettings(bool flag) { mCanEdit = flag; }
+
+    inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb)    { return mOnDirtyChanged.connect(cb); }
+
+
+protected:
+    LLSettingsEditPanel() :
+        LLPanel(),
+        mIsDirty(false),
+        mOnDirtyChanged()
+    {}
+
+private:
+    void onTextureChanged(LLUUID &inventory_item_id);
+
+    bool                mIsDirty;
+    bool                mCanEdit;
+    
+    on_dirty_charged_sg mOnDirtyChanged;
+};
+
+#endif // LL_FLOATERENVIRONMENTBASE_H
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index a7c2cbbeaa2d5e2f3c4948e63eb35821f97bff71..0501c287ad96605235339968a20d9e036752816e 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -125,7 +125,6 @@ namespace {
 }
 
 //=========================================================================
-const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id");
 const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");
 const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");
 const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
@@ -133,7 +132,7 @@ const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
 const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");
 const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
 const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
-
+/*
 //=========================================================================
 
 class LLDaySettingCopiedCallback : public LLInventoryCallback
@@ -156,12 +155,12 @@ class LLDaySettingCopiedCallback : public LLInventoryCallback
 
 private:
     LLHandle<LLFloater> mHandle;
-};
+};*/
 
 //=========================================================================
 
 LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
-    LLFloater(key),
+    LLFloaterEditEnvironmentBase(key),
     mFlyoutControl(nullptr),
     mDayLength(0),
     mCurrentTrack(1),
@@ -170,19 +169,12 @@ LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
     mFramesSlider(nullptr),
     mCurrentTimeLabel(nullptr),
     mImportButton(nullptr),
-    mInventoryId(),
-    mInventoryItem(nullptr),
     mLoadFrame(nullptr),
     mSkyBlender(),
     mWaterBlender(),
     mScratchSky(),
     mScratchWater(),
     mIsPlaying(false),
-    mIsDirty(false),
-    mCanSave(false),
-    mCanCopy(false),
-    mCanMod(false),
-    mCanTrans(false),
     mCloneTrack(nullptr),
     mLoadTrack(nullptr),
     mClearTrack(nullptr)
@@ -425,19 +417,6 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
     }
 }
 
-void LLFloaterEditExtDayCycle::onFocusReceived()
-{
-    if (isInVisibleChain())
-    {
-        updateEditEnvironment();
-        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
-    }
-}
-
-void LLFloaterEditExtDayCycle::onFocusLost()
-{
-}
-
 
 void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility)
 {
@@ -488,6 +467,10 @@ void LLFloaterEditExtDayCycle::refresh()
     LLFloater::refresh();
 }
 
+void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+    setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+}
 
 void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
 {
@@ -700,63 +683,6 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
     }
 }
 
-void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day)
-{
-    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-    if (0 == option)
-    {
-        std::string settings_name = response["message"].asString();
-
-        LLInventoryObject::correctInventoryName(settings_name);
-        if (settings_name.empty())
-        {
-            // Ideally notification should disable 'OK' button if name won't fit our requirements,
-            // for now either display notification, or use some default name
-            settings_name = "Unnamed";
-        }
-
-        if (mCanMod)
-        {
-            doApplyCreateNewInventory(day, settings_name);
-        }
-        else if (mInventoryItem)
-        {
-            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
-            LLUUID parent_id = mInventoryItem->getParentUUID();
-            if (marketplacelistings_id == parent_id)
-            {
-                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-            }
-
-            LLPointer<LLInventoryCallback> cb = new LLDaySettingCopiedCallback(getHandle());
-            copy_inventory_item(
-                gAgent.getID(),
-                mInventoryItem->getPermissions().getOwner(),
-                mInventoryItem->getUUID(),
-                parent_id,
-                settings_name,
-                cb);
-        }
-        else
-        {
-            LL_WARNS() << "Failed to copy day setting" << LL_ENDL;
-        }
-    }
-}
-
-void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/)
-{
-    if (!app_quitting)
-        checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
-    else
-        closeFloater();
-}
-
-void LLFloaterEditExtDayCycle::onButtonImport()
-{
-    checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); });
-}
-
 void LLFloaterEditExtDayCycle::onButtonLoadFrame()
 {
     doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null);
@@ -1053,35 +979,6 @@ void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
     selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
 }
 
-
-void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value)
-{
-    if (value)
-        setDirtyFlag();
-}
-
-void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb)
-{
-    if (isDirty())
-    {
-        LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType())
-            ("NAME", mEditDay->getName()));
-
-        // create and show confirmation textbox
-        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
-            [cb](const LLSD&notif, const LLSD&resp)
-            {
-                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-                if (opt == 0)
-                    cb();
-            });
-    }
-    else if (cb)
-    {
-        cb();
-    }
-}
-
 void LLFloaterEditExtDayCycle::onTimeSliderCallback()
 {
     stopPlay();
@@ -1435,106 +1332,6 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi
     return mCommitSignal.connect(cb);
 }
 
-void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans)
-{
-    if (inventoryId.isNull())
-    {
-        mInventoryItem = nullptr;
-        mInventoryId.setNull();
-        mCanSave = true;
-        mCanCopy = true;
-        mCanMod = true;
-        mCanTrans = true;
-        return;
-    }
-
-    mInventoryId = inventoryId;
-    LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
-    mInventoryItem = gInventory.getItem(mInventoryId);
-
-    if (!mInventoryItem)
-    {
-        LL_WARNS("ENVDAYEDIT") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
-
-        LLNotificationsUtil::add("CantFindInvItem");
-        closeFloater();
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    if (mInventoryItem->getAssetUUID().isNull())
-    {
-        LL_WARNS("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" <<  LL_ENDL;
-
-        LLNotificationsUtil::add("UnableEditItem");
-        closeFloater();
-
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    mCanSave = true;
-    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
-    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
-    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-
-    mExpectingAssetId = mInventoryItem->getAssetUUID();
-    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
-        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
-{
-    if (asset_id != mExpectingAssetId)
-    {
-        LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL;
-        return;
-    }
-    mExpectingAssetId.setNull();
-    clearDirtyFlag();
-
-    if (!settings || status)
-    {
-        LLSD args;
-        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
-        LLNotificationsUtil::add("FailedToFindSettings", args);
-        closeFloater();
-        return;
-    }
-
-    if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
-    {
-        mCanSave = false;
-        mCanCopy = false;
-        mCanMod = false;
-        mCanTrans = false;
-    }
-    else
-    {
-        if (mCanCopy)
-            settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
-        else
-            settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
-
-        if (mCanMod)
-            settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
-        else
-            settings->setFlag(LLSettingsBase::FLAG_NOMOD);
-
-        if (mCanTrans)
-            settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
-        else
-            settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
-
-        if (mInventoryItem)
-            settings->setName(mInventoryItem->getName());
-    }
-
-    setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
-}
-
 void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
 {
     if (!mEditDay)
@@ -1670,93 +1467,6 @@ void LLFloaterEditExtDayCycle::reblendSettings()
     mWaterBlender->setPosition(position);    
 }
 
-void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name)
-{
-    if (mInventoryItem)
-    {
-        LLUUID parent_id = mInventoryItem->getParentUUID();
-        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
-        LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-    else
-    {
-        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-        // This method knows what sort of settings object to create.
-        LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-}
-
-void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day)
-{
-    if (mInventoryId.isNull())
-        LLSettingsVOBase::createInventoryItem(day, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
-                [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    else
-        LLSettingsVOBase::updateInventoryItem(day, mInventoryId,
-                [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
-}
-
-void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day)
-{
-    U32 flags(0);
-
-    if (mInventoryItem)
-    {
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOMOD;
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOTRANS;
-    }
-
-    flags |= day->getFlags();
-    day->setFlag(flags);
-
-    if (where == ACTION_APPLY_LOCAL)
-    {
-        day->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
-        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day);
-    }
-    else if (where == ACTION_APPLY_PARCEL)
-    {
-        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
-
-        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
-        {
-            LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL;
-            LLNotificationsUtil::add("WLParcelApplyFail");
-            return;
-        }
-
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1);
-        }
-    }
-    else if (where == ACTION_APPLY_REGION)
-    {
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else
-        {
-            LLEnvironment::instance().updateRegion(day, -1, -1);
-        }
-    }
-    else
-    {
-        LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL;
-        return;
-    }
-
-}
-
 void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
 {
     if (!mCommitSignal.empty())
@@ -1793,51 +1503,6 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
     return mFramesSlider->canAddSliders();
 }
 
-void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
-{
-    LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
-
-    if (inventory_id.isNull() || !results["success"].asBoolean())
-    {
-        LLNotificationsUtil::add("CantCreateInventory");
-        return;
-    }
-    onInventoryCreated(asset_id, inventory_id);
-}
-
-void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
-{
-    bool can_trans = true;
-    if (mInventoryItem)
-    {
-        LLPermissions perms = mInventoryItem->getPermissions();
-
-        LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
-        
-        if (created_item)
-        {
-            can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
-            created_item->setPermissions(perms);
-            created_item->updateServer(false);
-        }
-    }
-
-    clearDirtyFlag();
-    setFocus(TRUE);                 // Call back the focus...
-    loadInventoryItem(inventory_id, can_trans);
-}
-
-void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
-{
-    LL_WARNS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
-
-    clearDirtyFlag();
-    if (inventory_id != mInventoryId)
-    {
-        loadInventoryItem(inventory_id);
-    }
-}
-
 void LLFloaterEditExtDayCycle::doImportFromDisk()
 {   // Load a a legacy Windlight XML from disk.
     (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
@@ -1864,21 +1529,6 @@ void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string
     setEditDayCycle(legacyday);
 }
 
-bool LLFloaterEditExtDayCycle::canUseInventory() const
-{
-    return LLEnvironment::instance().isInventoryEnabled();
-}
-
-bool LLFloaterEditExtDayCycle::canApplyRegion() const
-{
-    return gAgent.canManageEstate();
-}
-
-bool LLFloaterEditExtDayCycle::canApplyParcel() const
-{
-    return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
-}
-
 void LLFloaterEditExtDayCycle::startPlay()
 {
     doCloseInventoryFloater();
@@ -1983,14 +1633,8 @@ void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)
     }
 }
 
-void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+LLFloaterSettingsPicker * LLFloaterEditExtDayCycle::getSettingsPicker()
 {
-    cloneTrack(track_id, mCurrentTrack);
-}
-
-void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
-{
-//  LLUI::sWindow->setCursor(UI_CURSOR_WAIT);
     LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
 
     // Show the dialog
@@ -2003,7 +1647,17 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ
 
         picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });
     }
+    return picker;
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+{
+    cloneTrack(track_id, mCurrentTrack);
+}
 
+void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
+{
+    LLFloaterSettingsPicker *picker = getSettingsPicker();
     picker->setSettingsFilter(type);
     picker->setSettingsItemId(curritem);
     if (type == LLSettingsType::ST_DAYCYCLE)
@@ -2018,16 +1672,6 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ
     picker->setFocus(TRUE);
 }
 
-void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting)
-{
-    LLFloater* floaterp = mInventoryFloater.get();
-
-    if (floaterp)
-    {
-        floaterp->closeFloater(quitting);
-    }
-}
-
 void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
 {
     LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
@@ -2118,7 +1762,9 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID
 
     LLInventoryItem *inv_item = gInventory.getItem(item_id);
 
-    if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+    if (inv_item
+        && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())
+            || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())))
     {
         // Need to check if item is already no-transfer, otherwise make it no-transfer
         bool no_transfer = false;
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
index a0eb9d697747643a89cd7e1c8b14a24bfd3e9e33..43e91973bf6a642be3c704d68104b2eb5091ca9e 100644
--- a/indra/newview/llfloatereditextdaycycle.h
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -32,6 +32,7 @@
 #include <boost/signals2.hpp>
 
 #include "llenvironment.h"
+#include "llfloatereditenvironmentbase.h"
 
 class LLCheckBoxCtrl;
 class LLComboBox;
@@ -50,14 +51,13 @@ typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t;
 /**
  * Floater for creating or editing a day cycle.
  */
-class LLFloaterEditExtDayCycle final : public LLFloater
+class LLFloaterEditExtDayCycle final : public LLFloaterEditEnvironmentBase
 {
 	LOG_CLASS(LLFloaterEditExtDayCycle);
 
     friend class LLDaySettingCopiedCallback;
 
 public:
-    static const std::string    KEY_INVENTORY_ID;
     static const std::string    KEY_EDIT_CONTEXT;
     static const std::string    KEY_DAY_LENGTH;
     static const std::string    KEY_CANMOD;
@@ -82,8 +82,8 @@ class LLFloaterEditExtDayCycle final : public LLFloater
     virtual BOOL                postBuild() override;
     virtual void                onOpen(const LLSD& key) override;
     virtual void                onClose(bool app_quitting) override;
-    virtual void                onFocusReceived() override;
-    virtual void                onFocusLost() override;
+    //virtual void                onFocusReceived() override;
+    //virtual void                onFocusLost() override;
     virtual void                onVisibilityChange(BOOL new_visibility) override;
 
     connection_t                setEditCommitSignal(edit_commit_signal_t::slot_type cb);
@@ -97,10 +97,13 @@ class LLFloaterEditExtDayCycle final : public LLFloater
     LLUUID                      getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; }
     LLUUID                      getEditingInventoryId() { return mInventoryId; }
 
+    virtual LLSettingsBase::ptr_t getEditSettings()   const override { return mEditDay; }
+
 
     BOOL			            handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override;
 
-    BOOL                        isDirty() const override { return getIsDirty(); } 
+protected:
+    virtual void                setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;
 
 private:
     typedef std::function<void()> on_confirm_fn;
@@ -108,8 +111,8 @@ class LLFloaterEditExtDayCycle final : public LLFloater
 
 	// flyout response/click
 	void                        onButtonApply(LLUICtrl *ctrl, const LLSD &data);
-    virtual void                onClickCloseBtn(bool app_quitting = false) override;
-    void                        onButtonImport();
+    //virtual void                onClickCloseBtn(bool app_quitting = false) override;
+    //void                        onButtonImport();
     void                        onButtonLoadFrame();
     void                        onAddFrame();
 	void                        onRemoveFrame();
@@ -119,7 +122,6 @@ class LLFloaterEditExtDayCycle final : public LLFloater
 	void                        onCommitName(class LLLineEditor* caller, void* user_data);
 	void                        onTrackSelectionCallback(const LLSD& user_data);
 	void                        onPlayActionCallback(const LLSD& user_data);
-	void                        onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day);
 	// time slider clicked
 	void                        onTimeSliderCallback();
 	// a frame moved or frame selection changed
@@ -128,10 +130,6 @@ class LLFloaterEditExtDayCycle final : public LLFloater
     void                        onFrameSliderMouseDown(S32 x, S32 y, MASK mask);
     void                        onFrameSliderMouseUp(S32 x, S32 y, MASK mask);
 
-    void                        onPanelDirtyFlagChanged(bool);
-
-    void                        checkAndConfirmSettingsLoss(on_confirm_fn cb);
-
     void                        cloneTrack(U32 source_index, U32 dest_index);
     void                        cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index);
 	void                        selectTrack(U32 track_index, bool force = false);
@@ -148,25 +146,21 @@ class LLFloaterEditExtDayCycle final : public LLFloater
     void                        removeCurrentSliderFrame();
     void                        removeSliderFrame(F32 frame);
 
-    void                        loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true);
-    void                        onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
-
-    void                        doImportFromDisk();
+    virtual void                doImportFromDisk() override;
     void                        loadSettingFromFile(const std::vector<std::string>& filenames);
-    void                        doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name);
-    void                        doApplyUpdateInventory(const LLSettingsDay::ptr_t &day);
-    void                        doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day);
     void                        doApplyCommit(LLSettingsDay::ptr_t day);
     void                        onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
     void                        onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
     void                        onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
 
+
     void                        doOpenTrackFloater(const LLSD &args);
     void                        doCloseTrackFloater(bool quitting = false);
+    virtual LLFloaterSettingsPicker* getSettingsPicker() override;
     void                        onPickerCommitTrackId(U32 track_id);
 
     void                        doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem);
-    void                        doCloseInventoryFloater(bool quitting = false);
+    //void                        doCloseInventoryFloater(bool quitting = false);
     void                        onPickerCommitSetting(LLUUID item_id, S32 track);
     void                        onAssetLoadedForInsertion(LLUUID item_id,
                                                           LLUUID asset_id,
@@ -176,11 +170,7 @@ class LLFloaterEditExtDayCycle final : public LLFloater
                                                           S32 dest_track,
                                                           LLSettingsBase::TrackPosition dest_frame);
 
-    bool                        canUseInventory() const;
-    bool                        canApplyRegion() const;
-    bool                        canApplyParcel() const;
-
-    void                        updateEditEnvironment();
+    virtual void                updateEditEnvironment() override;
     void                        synchronizeTabs();
     void                        reblendSettings();
 
@@ -193,7 +183,7 @@ class LLFloaterEditExtDayCycle final : public LLFloater
 
     bool                        getIsDirty() const  { return mIsDirty; }
     void                        setDirtyFlag()      { mIsDirty = true; }
-    virtual void                clearDirtyFlag();
+    virtual void                clearDirtyFlag() override;
 
     bool                        isRemovingFrameAllowed();
     bool                        isAddingFrameAllowed();
@@ -218,11 +208,8 @@ class LLFloaterEditExtDayCycle final : public LLFloater
     LLView*                     mSkyTabLayoutContainer;
     LLView*                     mWaterTabLayoutContainer;
     LLTextBox*                  mCurrentTimeLabel;
-    LLUUID                      mInventoryId;
-    LLInventoryItem *           mInventoryItem;
     LLFlyoutComboBtnCtrl *      mFlyoutControl;
 
-    LLHandle<LLFloater>         mInventoryFloater;
     LLHandle<LLFloater>         mTrackFloater;
 
     LLTrackBlenderLoopingManual::ptr_t  mSkyBlender;
@@ -236,11 +223,6 @@ class LLFloaterEditExtDayCycle final : public LLFloater
     LLFrameTimer                mPlayTimer;
     F32                         mPlayStartFrame; // an env frame
     bool                        mIsPlaying;
-    bool                        mIsDirty;
-    bool                        mCanCopy;
-    bool                        mCanMod;
-    bool                        mCanTrans;
-    bool                        mCanSave;
 
     edit_commit_signal_t        mCommitSignal;
 
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index cd8e0a48e7c170f185be2ad12ce9839f1c2d97c1..41bbd5e8f9b1cfdcf0817ddf1402e810e94ac61a 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -81,44 +81,11 @@ namespace
     const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
 }
 
-//=========================================================================
-const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id");
-
-
-//=========================================================================
-
-class LLFixedSettingCopiedCallback : public LLInventoryCallback
-{
-public:
-    LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
-
-    virtual void fire(const LLUUID& inv_item_id)
-    {
-        if (!mHandle.isDead())
-        {
-            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
-            if (item)
-            {
-                LLFloaterFixedEnvironment* floater = (LLFloaterFixedEnvironment*)mHandle.get();
-                floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
-            }
-        }
-    }
-
-private:
-    LLHandle<LLFloater> mHandle;
-};
 
 //=========================================================================
 LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) :
-    LLFloater(key),
-    mFlyoutControl(nullptr),
-    mInventoryId(),
-    mInventoryItem(nullptr),
-    mIsDirty(false),
-    mCanCopy(false),
-    mCanMod(false),
-    mCanTrans(false)
+    LLFloaterEditEnvironmentBase(key),
+    mFlyoutControl(nullptr)
 {
 }
 
@@ -176,19 +143,6 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting)
     syncronizeTabs();
 }
 
-void LLFloaterFixedEnvironment::onFocusReceived()
-{
-    if (isInVisibleChain())
-    {
-        updateEditEnvironment();
-        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
-    }
-}
-
-void LLFloaterFixedEnvironment::onFocusLost()
-{
-}
-
 void LLFloaterFixedEnvironment::refresh()
 {
     if (!mSettings)
@@ -220,6 +174,15 @@ void LLFloaterFixedEnvironment::refresh()
     }
 }
 
+void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+    mSettings = settings; // shouldn't this do buildDeepCloneAndUncompress() ?
+    updateEditEnvironment();
+    syncronizeTabs();
+    refresh();
+    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST);
+}
+
 void LLFloaterFixedEnvironment::syncronizeTabs()
 {
     S32 count = mTab->getTabCount();
@@ -250,131 +213,9 @@ LLFloaterSettingsPicker * LLFloaterFixedEnvironment::getSettingsPicker()
     return picker;
 }
 
-void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans)
-{
-    if (inventoryId.isNull())
-    {
-        mInventoryItem = nullptr;
-        mInventoryId.setNull();
-        mCanMod = true;
-        mCanCopy = true;
-        mCanTrans = true;
-        return;
-    }
-
-    mInventoryId = inventoryId;
-    LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
-    mInventoryItem = gInventory.getItem(mInventoryId);
-
-    if (!mInventoryItem)
-    {
-        LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
-        LLNotificationsUtil::add("CantFindInvItem");
-        closeFloater();
-
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    if (mInventoryItem->getAssetUUID().isNull())
-    {
-        LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
-        LLNotificationsUtil::add("UnableEditItem");
-        closeFloater();
-
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
-    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
-    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-
-    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
-        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-
-void LLFloaterFixedEnvironment::checkAndConfirmSettingsLoss(LLFloaterFixedEnvironment::on_confirm_fn cb)
-{
-    if (isDirty())
-    {
-        LLSD args(LLSDMap("TYPE", mSettings->getSettingsType())
-            ("NAME", mSettings->getName()));
-
-        // create and show confirmation textbox
-        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
-            [cb](const LLSD&notif, const LLSD&resp)
-            {
-                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-                if (opt == 0)
-                    cb();
-            });
-    }
-    else if (cb)
-    {
-        cb();
-    }
-}
-
 void LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID item_id)
 {
     loadInventoryItem(item_id);
-//     mInventoryId = item_id;
-//     mInventoryItem = gInventory.getItem(mInventoryId);
-// 
-//     mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
-//     mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
-//     mCanTrans = mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-// 
-//     LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
-//         [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
-{
-    if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id)
-    {
-        LL_WARNS("ENVIRONMENT") << "Discarding obsolete asset callback" << LL_ENDL;
-        return;
-    }
-
-    clearDirtyFlag();
-
-    if (!settings || status)
-    {
-        LLSD args;
-        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
-        LLNotificationsUtil::add("FailedToFindSettings", args);
-        closeFloater();
-        return;
-    }
-
-    mSettings = settings;
-    if (mInventoryItem)
-        mSettings->setName(mInventoryItem->getName());
-
-    if (mCanCopy)
-        settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
-    else
-        settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
-
-    if (mCanMod)
-        settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
-    else
-        settings->setFlag(LLSettingsBase::FLAG_NOMOD);
-
-    if (mCanTrans)
-        settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
-    else
-        settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
-
-    updateEditEnvironment();
-    syncronizeTabs();
-    refresh();
-    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST);
 }
 
 void LLFloaterFixedEnvironment::onNameChanged(const std::string &name)
@@ -473,50 +314,6 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
     }
 }
 
-void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings)
-{
-    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-    if (0 == option)
-    {
-        std::string settings_name = response["message"].asString();
-
-        LLInventoryObject::correctInventoryName(settings_name);
-        if (settings_name.empty())
-        {
-            // Ideally notification should disable 'OK' button if name won't fit our requirements,
-            // for now either display notification, or use some default name
-            settings_name = "Unnamed";
-        }
-
-        if (mCanMod)
-        {
-            doApplyCreateNewInventory(settings_name, settings);
-        }
-        else if (mInventoryItem)
-        {
-            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
-            LLUUID parent_id = mInventoryItem->getParentUUID();
-            if (marketplacelistings_id == parent_id)
-            {
-                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-            }
-
-            LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle());
-            copy_inventory_item(
-                gAgent.getID(),
-                mInventoryItem->getPermissions().getOwner(),
-                mInventoryItem->getUUID(),
-                parent_id,
-                settings_name,
-                cb);
-        }
-        else
-        {
-            LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL;
-        }
-    }
-}
-
 void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting)
 {
     if (!app_quitting)
@@ -530,116 +327,6 @@ void LLFloaterFixedEnvironment::onButtonLoad()
     checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); });
 }
 
-void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings)
-{
-    if (mInventoryItem)
-    {
-        LLUUID parent_id = mInventoryItem->getParentUUID();
-        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
-        LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-    else
-    {
-        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-        // This method knows what sort of settings object to create.
-        LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-}
-
-void LLFloaterFixedEnvironment::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings)
-{
-    LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL;
-    if (mInventoryId.isNull())
-    {
-        LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-    else
-    {
-        LLSettingsVOBase::updateInventoryItem(settings, mInventoryId,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
-    }
-}
-
-void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings)
-{
-    U32 flags(0);
-
-    if (mInventoryItem)
-    {
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOMOD;
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOTRANS;
-    }
-
-    flags |= settings->getFlags();
-    settings->setFlag(flags);
-
-    if (where == ACTION_APPLY_LOCAL)
-    {
-        settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
-        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings);
-    }
-    else if (where == ACTION_APPLY_PARCEL)
-    {
-        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
-
-        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
-        {
-            LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL;
-            LLNotificationsUtil::add("WLParcelApplyFail");
-            return;
-        }
-
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else if (settings->getSettingsType() == "sky")
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
-        }
-        else if (settings->getSettingsType() == "water")
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
-        }
-    }
-    else if (where == ACTION_APPLY_REGION)
-    {
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else if (settings->getSettingsType() == "sky")
-        {
-            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
-        }
-        else if (settings->getSettingsType() == "water")
-        {
-            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
-        }
-    }
-    else
-    {
-        LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL;
-        return;
-    }
-
-}
-
-void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting)
-{
-    LLFloater* floaterp = mInventoryFloater.get();
-
-    if (floaterp)
-    {
-        floaterp->closeFloater(quitting);
-    }
-}
-
 void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
 {
     LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
@@ -709,28 +396,6 @@ void LLFloaterFixedEnvironment::doSelectFromInventory()
     picker->setFocus(TRUE);
 }
 
-void LLFloaterFixedEnvironment::onPanelDirtyFlagChanged(bool value)
-{
-    if (value)
-        setDirtyFlag();
-}
-
-//-------------------------------------------------------------------------
-bool LLFloaterFixedEnvironment::canUseInventory() const
-{
-    return LLEnvironment::instance().isInventoryEnabled();
-}
-
-bool LLFloaterFixedEnvironment::canApplyRegion() const
-{
-    return gAgent.canManageEstate();
-}
-
-bool LLFloaterFixedEnvironment::canApplyParcel() const
-{
-    return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
-}
-
 //=========================================================================
 LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key):
     LLFloaterFixedEnvironment(key)
diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h
index 08583dc6c5ed34629273c3be827ac1386a6e275d..5f2a1e13bd3cf3c60de3933256281f39404d7398 100644
--- a/indra/newview/llfloaterfixedenvironment.h
+++ b/indra/newview/llfloaterfixedenvironment.h
@@ -27,7 +27,7 @@
 #ifndef LL_FLOATERFIXEDENVIRONMENT_H
 #define LL_FLOATERFIXEDENVIRONMENT_H
 
-#include "llfloater.h"
+#include "llfloatereditenvironmentbase.h"
 #include "llsettingsbase.h"
 #include "llflyoutcombobtn.h"
 #include "llinventory.h"
@@ -43,15 +43,10 @@ class LLFixedSettingCopiedCallback;
 /**
  * Floater container for creating and editing fixed environment settings.
  */
-class LLFloaterFixedEnvironment : public LLFloater
+class LLFloaterFixedEnvironment : public LLFloaterEditEnvironmentBase
 {
     LOG_CLASS(LLFloaterFixedEnvironment);
-
-    friend class LLFixedSettingCopiedCallback;
-
 public:
-    static const std::string    KEY_INVENTORY_ID;
-
                             LLFloaterFixedEnvironment(const LLSD &key);
                             ~LLFloaterFixedEnvironment();
 
@@ -59,64 +54,35 @@ class LLFloaterFixedEnvironment : public LLFloater
     virtual void            onOpen(const LLSD& key)     override;
     virtual void            onClose(bool app_quitting)  override;
 
-    virtual void            onFocusReceived()           override;
-    virtual void            onFocusLost()               override;
-
     void                    setEditSettings(const LLSettingsBase::ptr_t &settings)  { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); }
-    LLSettingsBase::ptr_t   getEditSettings()   const                           { return mSettings; }
-
-    virtual BOOL            isDirty() const override            { return getIsDirty(); }
+    virtual LLSettingsBase::ptr_t getEditSettings()   const override                { return mSettings; }
 
 protected:
     typedef std::function<void()> on_confirm_fn;
 
-    virtual void            updateEditEnvironment() = 0;
     virtual void            refresh()                   override;
+    void                    setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;
     virtual void            syncronizeTabs();
 
-    LLFloaterSettingsPicker *getSettingsPicker();
-
-    void                    loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true);
-
-    void                    checkAndConfirmSettingsLoss(on_confirm_fn cb);
+    virtual LLFloaterSettingsPicker *getSettingsPicker() override;
 
     LLTabContainer *        mTab;
     LLLineEditor *          mTxtName;
 
     LLSettingsBase::ptr_t   mSettings;
 
-    virtual void            doImportFromDisk() = 0;
-    virtual void            doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings);
-    virtual void            doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings);
-    virtual void            doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings);
-    void                    doCloseInventoryFloater(bool quitting = false);
-
-    bool                    canUseInventory() const;
-    bool                    canApplyRegion() const;
-    bool                    canApplyParcel() const;
-
     LLFlyoutComboBtnCtrl *      mFlyoutControl;
 
-    LLUUID                  mInventoryId;
-    LLInventoryItem *       mInventoryItem;
-    LLHandle<LLFloater>     mInventoryFloater;
-    bool                    mCanCopy;
-    bool                    mCanMod;
-    bool                    mCanTrans;
-
     void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
     void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
     void                    onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
 
-    bool                    getIsDirty() const  { return mIsDirty; }
-    void                    setDirtyFlag()      { mIsDirty = true; }
-    virtual void            clearDirtyFlag();
+    virtual void            clearDirtyFlag() override;
+    void                    updatePermissionFlags();
 
     void                    doSelectFromInventory();
-    void                    onPanelDirtyFlagChanged(bool);
 
     virtual void            onClickCloseBtn(bool app_quitting = false) override;
-    void                    onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings);
 
 private:
     void                    onNameChanged(const std::string &name);
@@ -126,9 +92,6 @@ class LLFloaterFixedEnvironment : public LLFloater
     void                    onButtonLoad();
 
     void                    onPickerCommitSetting(LLUUID item_id);
-    void                    onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
-
-    bool                    mIsDirty;
 };
 
 class LLFloaterFixedEnvironmentWater final : public LLFloaterFixedEnvironment
@@ -172,36 +135,4 @@ class LLFloaterFixedEnvironmentSky final : public LLFloaterFixedEnvironment
 private:
 };
 
-class LLSettingsEditPanel : public LLPanel
-{
-public:
-    virtual void setSettings(const LLSettingsBase::ptr_t &) = 0;
-
-    typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg;
-    typedef boost::signals2::connection connection_t;
-
-    inline bool         getIsDirty() const      { return mIsDirty; }
-    inline void         setIsDirty()            { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
-    inline void         clearIsDirty()          { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
-
-    inline bool        getCanChangeSettings() const    { return mCanEdit; }
-    inline void        setCanChangeSettings(bool flag) { mCanEdit = flag; }
-
-    inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb)    { return mOnDirtyChanged.connect(cb); }
-
-
-protected:
-    LLSettingsEditPanel() :
-        LLPanel(),
-        mIsDirty(false),
-        mOnDirtyChanged()
-    {}
-
-private:
-    bool                mIsDirty;
-    bool                mCanEdit;
-    
-    on_dirty_charged_sg mOnDirtyChanged;
-};
-
 #endif // LL_FLOATERFIXEDENVIRONMENT_H
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index b052cf3b95bea85d57d1a9af9cde2812eb0208a3..59778a3a64c17d5a31ccf7108f982df75e0a5cc9 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -313,12 +313,15 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 
 	
 	LLIconCtrl* icon = 0;
+	bool is_in_group = gAgent.isInGroup(session_id, TRUE);
+	LLUUID icon_id;
 
-	if(gAgent.isInGroup(session_id, TRUE))
+	if (is_in_group)
 	{
 		LLGroupIconCtrl::Params icon_params;
 		icon_params.group_id = session_id;
 		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+		icon_id = session_id;
 
 		mSessions[session_id] = floaterp;
 		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
@@ -330,11 +333,18 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 		LLAvatarIconCtrl::Params icon_params;
 		icon_params.avatar_id = avatar_id;
 		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+		icon_id = avatar_id;
 
 		mSessions[session_id] = floaterp;
 		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
 	}
 
+	LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id);
+	if (floater)
+	{
+		floater->updateChatIcon(icon_id);
+	}
+
 	// forced resize of the floater
 	LLRect wrapper_rect = this->mTabContainer->getLocalRect();
 	floaterp->setRect(wrapper_rect);
@@ -1873,6 +1883,8 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 		{
 			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
 		}
+
+		// Will destroy views and delete models that are not assigned to any views
 		widget->destroyView();
 	}
 	
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 7e50d6a7b406329c2090706a7f9899d0c11a8e08..4cbf11ffaa7aec6997524daca06b0fb704354965 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -32,6 +32,8 @@
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
 #include "llchatentry.h"
 #include "llchathistory.h"
 #include "llchiclet.h"
@@ -45,6 +47,9 @@
 #include "llfloaterimnearbychat.h"
 
 const F32 REFRESH_INTERVAL = 1.0f;
+const std::string ICN_GROUP("group_chat_icon");
+const std::string ICN_NEARBY("nearby_chat_icon");
+const std::string ICN_AVATAR("avatar_icon");
 
 void cb_group_do_nothing()
 {
@@ -532,8 +537,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
 	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
 	if (widget)
 	{
-		mConversationsRoot->extractItem(widget);
-		delete widget;
+		widget->destroyView();
 	}
 	mConversationsWidgets.erase(participant_id);
 }
@@ -702,6 +706,39 @@ void LLFloaterIMSessionTab::updateSessionName(const std::string& name)
 	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
 }
 
+void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id)
+{
+	if (mSession)
+	{
+		if (mSession->isP2PSessionType())
+		{
+			LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>(ICN_AVATAR);
+			icon->setVisible(true);
+			icon->setValue(id);
+		}
+		if (mSession->isAdHocSessionType())
+		{
+			LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP);
+			icon->setVisible(true);
+		}
+		if (mSession->isGroupSessionType())
+		{
+			LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP);
+			icon->setVisible(true);
+			icon->setValue(id);
+		}
+	}
+	else
+	{
+		if (mIsNearbyChat)
+		{
+			LLIconCtrl* icon = getChild<LLIconCtrl>(ICN_NEARBY);
+			icon->setVisible(true);
+		}
+	}
+
+}
+
 void LLFloaterIMSessionTab::hideAllStandardButtons()
 {
 	for (S32 i = 0; i < BUTTON_COUNT; i++)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e792c0f2613a3087d84b961d0ad3e5579d47354c..ba5a372df4a909ee0c5f9e27442f64e3ad973e9e 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -103,6 +103,8 @@ class LLFloaterIMSessionTab
 	void restoreFloater();
 	void saveCollapsedState();
 
+	void updateChatIcon(const LLUUID& id);
+
 	LLView* getChatHistory();
 
 protected:
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 889d01738931f4ed4e7eae31c913840b8ecea1bf..524162ba513badb0bf3ff12ee459a2649ba84968 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -103,14 +103,17 @@ void LLPanelMarketplaceListings::buildAllPanels()
     panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml");
 	panel->getFilter().setFilterMarketplaceActiveFolders();
 	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
 	panel->getFilter().markDefault();
     panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml");
 	panel->getFilter().setFilterMarketplaceInactiveFolders();
 	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
 	panel->getFilter().markDefault();
     panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml");
 	panel->getFilter().setFilterMarketplaceUnassociatedFolders();
 	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
 	panel->getFilter().markDefault();
 
     // Set the tab panel
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 318197e61d7f8ca476ada29196a71332f7314511..204d9741e8a1c8dd3e28bdbdaffef2d926faed4a 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -103,6 +103,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
 
 void LLMeshFilePicker::notify(const std::vector<std::string>& filenames)
 {
+	if(LLAppViewer::instance()->quitRequested())
+	{
+		return;
+	}
+	
 	if (filenames.size() > 0)
 	{
 		mMP->loadModel(filenames[0], mLOD);
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e8b93deb3966e0515f17c4faa30b7a1a1274c73d..db579f95cf05a25506f84e2ae249e686cf670836 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -39,6 +39,7 @@
 #include "llfloaterimcontainer.h"
 #include "llimview.h" // for gIMMgr
 #include "llnotificationsutil.h"
+#include "llstartup.h"
 #include "llstatusbar.h"	// can_afford_transaction()
 #include "groupchatlistener.h"
 // [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0)
@@ -61,6 +62,11 @@ class LLGroupCommandHandler : public LLCommandHandler
 	bool handle(const LLSD& tokens, const LLSD& query_map,
 				LLMediaCtrl* web)
 	{
+		if (LLStartUp::getStartupState() < STATE_STARTED)
+		{
+			return true;
+		}
+
 		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo"))
 		{
 			LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index db234367838ad6d74a2af1154a78e4b68384d65f..a8eb970b85ad27d536b9b766b985a330ccde9d96 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -978,6 +978,9 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 			// Incoming P2P sessions include a name that we can use to build a history file name
 			mHistoryFileName = LLCacheName::buildUsername(mName);
 		}
+
+        // user's account name can change, but filenames and session names are account name based
+        LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName, av_name.getCompleteName());
 	}
 	else if (isGroupChat())
 	{
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index d9483d22ae55cfb328cad76bd48d143fa03e4a57..7471ffafd29c8fbcd68580970078914b1a8791ee 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -74,6 +74,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 :	mName(p.name),
 	mFilterModified(FILTER_NONE),
 	mEmptyLookupMessage("InventoryNoMatchingItems"),
+	mDefaultEmptyLookupMessage(""),
 	mFilterOps(p.filter_ops),
 	mBackupFilterOps(mFilterOps),
 	mFilterSubString(p.substring),
@@ -1440,12 +1441,24 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
 	mEmptyLookupMessage = message;
 }
 
+void LLInventoryFilter::setDefaultEmptyLookupMessage(const std::string& message)
+{
+	mDefaultEmptyLookupMessage = message;
+}
+
 std::string LLInventoryFilter::getEmptyLookupMessage() const
 {
-	LLStringUtil::format_map_t args;
-	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+	if (isDefault() && !mDefaultEmptyLookupMessage.empty())
+	{
+		return LLTrans::getString(mDefaultEmptyLookupMessage);
+	}
+	else
+	{
+		LLStringUtil::format_map_t args;
+		args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
 
-	return LLTrans::getString(mEmptyLookupMessage, args);
+		return LLTrans::getString(mEmptyLookupMessage, args);
+	}
 
 }
 
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index be02ee3623b2e922eec8dbf12a83c2f3d2dd8231..61cc5ae602d5da80130fdb6eb66af4e6d636cac9 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -257,6 +257,7 @@ class LLInventoryFilter : public LLFolderViewFilter
 	EFilterCreatorType		getFilterCreatorType() const;
 
 	void 				setEmptyLookupMessage(const std::string& message);
+	void				setDefaultEmptyLookupMessage(const std::string& message);
 	std::string			getEmptyLookupMessage() const;
 
 	// +-------------------------------------------------------------------+
@@ -332,6 +333,7 @@ class LLInventoryFilter : public LLFolderViewFilter
     
 	std::string 			mFilterText;
 	std::string 			mEmptyLookupMessage;
+	std::string				mDefaultEmptyLookupMessage;
 
 	ESearchType 			mSearchType;
 
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 88903e6a90de9a6c23e57311f4dc48b576aa8f88..82d4ea5dbf82db6b10b9f25dfc71d33536c2579b 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -107,11 +107,13 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
             return NULL;
         }
 
+        mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+        // Note that getAssetData can callback immediately and cleans mRequestedList
 		gAssetStorage->getAssetData(asset_uuid,
 									LLAssetType::AT_LANDMARK,
 									LLLandmarkList::processGetAssetReply,
 									NULL);
-		mRequestedList[asset_uuid] = gFrameTimeSeconds;
 	}
 	return NULL;
 }
@@ -199,11 +201,15 @@ void LLLandmarkList::processGetAssetReply(
             landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
             LLUUID asset_uuid = *iter;
             gLandmarkList.mWaitList.erase(iter);
+
+            // add to mRequestedList before calling getAssetData()
+            gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+            // Note that getAssetData can callback immediately and cleans mRequestedList
             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 f2f311919d4a59497157a49a6caf0d857eb9f952..24b42a17af8cc915dff1b182b2b7b7c3dac911b4 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -268,6 +268,28 @@ std::string LLLogChat::makeLogFileName(std::string filename)
 	return filename;
 }
 
+//static
+void LLLogChat::renameLogFile(const std::string& old_filename, const std::string& new_filename)
+{
+    std::string new_name = cleanFileName(new_filename);
+    std::string old_name = cleanFileName(old_filename);
+    new_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, new_name);
+    old_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, old_name);
+
+    if (new_name.empty() || old_name.empty())
+    {
+        return;
+    }
+
+    new_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+    old_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
+    if (!LLFile::isfile(new_name) && LLFile::isfile(old_name))
+    {
+        LLFile::rename(old_name, new_name);
+    }
+}
+
 std::string LLLogChat::cleanFileName(std::string filename)
 {
 	std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index d2a1566473cdedefb1ecb25eb832bdb0fb55610f..ea870f8e9936f652a5ffb58d52a330b81d8b7ac3 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -94,6 +94,7 @@ class LLLogChat final : public LLSingleton<LLLogChat>
 
 	static std::string timestamp(bool withdate = false);
 	static std::string makeLogFileName(std::string(filename));
+	static void renameLogFile(const std::string& old_filename, const std::string& new_filename);
 	/**
 	*Add functions to get old and non date stamped file names when needed
 	*/
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 3c2dc8c7d0062a946e0e0b707247f94b260ef9c6..824057c4e2933217d4ee73bb60f8b49e94ef90bf 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -58,6 +58,7 @@
 #include "llevents.h"
 #include "llappviewer.h"
 #include "llsdserialize.h"
+#include "lltrans.h"
 
 #include <sstream>
 
@@ -331,7 +332,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
         {
             data["certificate"] = response["certificate"];
         }
-        
+
         if (gViewerWindow)
             gViewerWindow->setShowProgress(FALSE);
 
@@ -348,13 +349,36 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
         // login.cgi is insisting on a required update. We were called with an
         // event that bundles both the login.cgi 'response' and the
         // synchronization event from the 'updater'.
-        std::string required_version = response["message_args"]["VERSION"];
-        LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
+        std::string login_version = response["message_args"]["VERSION"];
+        std::string vvm_version   = updater["VERSION"];
+        std::string relnotes      = updater["URL"];
+        LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL;
+        // vvm_version might be empty because we might not have gotten
+        // SLVersionChecker's LoginSync handshake. But if it IS populated, it
+        // should (!) be the same as the version we got from login.cgi.
+        if ((! vvm_version.empty()) && vvm_version != login_version)
+        {
+            LL_WARNS("LLLogin") << "VVM update version " << vvm_version
+                                << " differs from login version " << login_version
+                                << "; presenting VVM version to match release notes URL"
+                                << LL_ENDL;
+            login_version = vvm_version;
+        }
+        if (relnotes.empty() || relnotes.find("://") == std::string::npos)
+        {
+            relnotes = LLTrans::getString("RELEASE_NOTES_BASE_URL");
+            if (!LLStringUtil::endsWith(relnotes, "/"))
+                relnotes += "/";
+            relnotes += LLURI::escape(login_version) + ".html";
+        }
 
         if (gViewerWindow)
             gViewerWindow->setShowProgress(FALSE);
 
-        LLSD args(LLSDMap("VERSION", required_version));
+        LLSD args;
+        args["VERSION"] = login_version;
+        args["URL"] = relnotes;
+
         if (updater.isUndefined())
         {
             // If the updater failed to shake hands, better advise the user to
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index c044c9d696e2c072ed3b2ac8f46ecdcace2bfc6e..6fd9e3267865809177b3f11d94ebb34f281d548b 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -297,6 +297,7 @@ class LLHandlerUtil
 	 * Writes notification message to IM  p2p session.
 	 */
 	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
+	static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false);
 
 	/**
 	 * Writes group notice notification message to IM  group session.
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 1e1f243653fd8739537ce71ded9e0a5c38b6e03e..cb3086ee702af589fc8947d7202b50c93f7ed18f 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -123,15 +123,13 @@ void log_name_callback(const LLAvatarName& av_name, const std::string& from_name
 }
 
 // static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only)
 {
 	if (!gCacheName)
 	{
 		return;
 	}
 
-	LLUUID from_id = notification->getPayload()["from_id"];
-
 	if (from_id.isNull())
 	{
 		// Normal behavior for system generated messages, don't spam.
@@ -141,14 +139,21 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
 
 	if(to_file_only)
 	{
-		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID()));
 	}
 	else
 	{
-		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id));
 	}
 }
 
+// static
+void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+{
+	LLUUID from_id = notification->getPayload()["from_id"];
+	logToIMP2P(from_id, notification->getMessage(), to_file_only);	
+}
+
 // static
 void LLHandlerUtil::logGroupNoticeToIMGroup(
 		const LLNotificationPtr& notification)
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index d4898bb497deb97d68579e5f964eefb4110e0001..58ff2b92c2b0d5e934319e5143b79216eef45d01 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,6 +40,8 @@
 #include "rlvactions.h"
 // [/RLVa:KB]
 
+#include <boost/regex.hpp>
+
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
@@ -158,7 +160,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 		{
 			// log only to file if notif panel can be embedded to IM and IM is opened
 			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
-			LLHandlerUtil::logToIMP2P(notification, file_only);
+			if ((notification->getName() == "TeleportOffered"
+				|| notification->getName() == "TeleportOffered_MaturityExceeded"
+				|| notification->getName() == "TeleportOffered_MaturityBlocked"))
+			{
+				boost::regex r("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>( - )?",
+					boost::regex::perl|boost::regex::icase);
+				std::string stripped_msg = boost::regex_replace(notification->getMessage(), r, "");
+				LLHandlerUtil::logToIMP2P(notification->getPayload()["from_id"], stripped_msg,file_only);
+			}
+			else
+			{
+				LLHandlerUtil::logToIMP2P(notification, file_only);
+			}
 		}
 	}
 
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
index c02c9c95a0c2cc8a84c68e7a05a35a67de5cd1c8..801fb8b9b263f02ca3951d5d2465fe4ab17b579b 100644
--- a/indra/newview/llpaneleditsky.h
+++ b/indra/newview/llpaneleditsky.h
@@ -29,7 +29,7 @@
 
 #include "llpanel.h"
 #include "llsettingssky.h"
-#include "llfloaterfixedenvironment.h"
+#include "llfloatereditenvironmentbase.h"
 
 //=========================================================================
 class LLSlider;
diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h
index 20357e3d85cc67d74fba643c7aab5e7256431000..3bb0cf333a4e9afa1a717385269a572806a736f5 100644
--- a/indra/newview/llpaneleditwater.h
+++ b/indra/newview/llpaneleditwater.h
@@ -30,7 +30,7 @@
 #include "llpanel.h"
 #include "llsettingswater.h"
 
-#include "llfloaterfixedenvironment.h"
+#include "llfloatereditenvironmentbase.h"
 
 //=========================================================================
 class LLSlider;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index fb982c75f98791df34d4ae6c64904596df555590..3300644b86d364adb4fbba3451df792020232573 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -540,6 +540,16 @@ void LLPanelLogin::show(const LLRect &rect,
 	gFocusMgr.setDefaultKeyboardFocus(sInstance);
 }
 
+//static
+void LLPanelLogin::reshapePanel()
+{
+    if (sInstance)
+    {
+        LLRect rect = sInstance->getRect();
+        sInstance->reshape(rect.getWidth(), rect.getHeight());
+    }
+}
+
 //static
 void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
 {
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c7a22e7ed61929d2cc3175e61ceffe2dd3e33ed5..8b4bcbebfedd71cda1cc005499def783909081a6 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -53,6 +53,7 @@ class LLPanelLogin:
 	static void show(const LLRect &rect,
 		void (*callback)(S32 option, void* user_data), 
 		void* callback_data);
+	static void reshapePanel();
 
 	static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
 	static void resetFields();
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index ab8d7bd74910c213cf07cbd8914e05c464888416..7322b487e388e62aec31dde8ab3b90ad10e72806 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -74,6 +74,8 @@ const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels
 const int LLPanelPrimMediaControls::kNumZoomLevels = 2;
 
 const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f;
+const S32 ADDR_LEFT_PAD = 3;
+
 //
 // LLPanelPrimMediaControls
 //
@@ -156,7 +158,7 @@ BOOL LLPanelPrimMediaControls::postBuild()
 	mMediaProgressPanel		= getChild<LLPanel>("media_progress_indicator");
 	mMediaProgressBar		= getChild<LLProgressBar>("media_progress_bar");
 	mMediaAddressCtrl		= getChild<LLUICtrl>("media_address");
-	mMediaAddress			= getChild<LLUICtrl>("media_address_url");
+	mMediaAddress			= getChild<LLLineEditor>("media_address_url");
 	mMediaPlaySliderPanel	= getChild<LLUICtrl>("media_play_position");
 	mMediaPlaySliderCtrl	= getChild<LLUICtrl>("media_play_slider");
 	mSkipFwdCtrl			= getChild<LLUICtrl>("skip_forward");
@@ -502,8 +504,10 @@ void LLPanelPrimMediaControls::updateShape()
 			std::string test_prefix = mCurrentURL.substr(0, prefix.length());
 			LLStringUtil::toLower(test_prefix);
             mSecureURL = has_focus && (test_prefix == prefix);
-            mCurrentURL = (mSecureURL ? "      " + mCurrentURL : mCurrentURL);
-			
+
+			S32 left_pad = mSecureURL ? mSecureLockIcon->getRect().getWidth() : ADDR_LEFT_PAD;
+			mMediaAddress->setTextPadding(left_pad, 0);
+
 			if(mCurrentURL!=mPreviousURL)
 			{
 				setCurrentURL();
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index 86fc03655389f24e5138dd6345249e735e453661..dd0e4ff095f869eacc6d1f87c78ddc66ab233b4a 100644
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -39,6 +39,7 @@ class LLProgressBar;
 class LLSliderCtrl;
 class LLViewerMediaImpl;
 class LLWindowShade;
+class LLLineEditor;
 
 class LLPanelPrimMediaControls : public LLPanel
 {
@@ -164,7 +165,7 @@ class LLPanelPrimMediaControls : public LLPanel
 	LLPanel  *mMediaProgressPanel;
 	LLProgressBar *mMediaProgressBar;
 	LLUICtrl *mMediaAddressCtrl;
-	LLUICtrl *mMediaAddress;
+	LLLineEditor *mMediaAddress;
 	LLUICtrl *mMediaPlaySliderPanel;
 	LLUICtrl *mMediaPlaySliderCtrl;
 	LLUICtrl *mVolumeCtrl;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index bdaee694958ab8fffab0e958a577a182e6728d2e..a0567507b3a0d27634a0070ced6aa7d358eda301 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -256,11 +256,7 @@ LLParticipantList::~LLParticipantList()
 */
 void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
 {
-	LLConversationItemParticipant* participant = findParticipant(participant_id);
-	if (participant)
-	{
-		removeParticipant(participant);
-	}
+	removeParticipant(participant_id);
 	// re-add avaline caller with a correct class instance.
 	addAvatarIDExceptAgent(participant_id);
 }
@@ -394,6 +390,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
 	
 	// Add the participant model to the session's children list
+	// This will post "add_participant" event
 	addParticipant(participant);
 
 	adjustParticipant(avatar_id);
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 15a2a4994b6a0ddc1929f5fc78d4e8a6a917105f..9c6ea8401075f87d158c7c82d436d6614cd18996 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -772,7 +772,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
 		}
 		if (immediate || (mLiveHelpTimer.getStarted() && mLiveHelpTimer.getElapsedTimeF32() > LIVE_HELP_REFRESH_TIME))
 		{
-			std::string help_string = mEditor->getText().substr(segment->getStart(), segment->getEnd() - segment->getStart());
+			// Use Wtext since segment's start/end are made for wstring and will
+			// result in a shift for case of multi-byte symbols inside std::string.
+			LLWString segment_text = mEditor->getWText().substr(segment->getStart(), segment->getEnd() - segment->getStart());
+			std::string help_string = wstring_to_utf8str(segment_text);
 			setHelpPage(help_string);
 			mLiveHelpTimer.stop();
 		}
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 3d6493d3abd09335cb7ed2939a75fdc9a6320266..cd1ea809a19ea1ea0da39b7483ab8cbe141d62ec 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -530,157 +530,163 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
 	if (!hasResults()) return;
 
 	LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL; 
-
-	llofstream os(file_name.c_str());
-
-	os << std::setprecision(10);
-
-	LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
-	const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
-
-	F64Seconds frame_time;
-
-	os << "Stat";
-	for (S32 frame = 1; frame <= frame_count; frame++)
+	try
 	{
-		frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
-		os << ", " << frame_time.value();
-	}
-	os << '\n';
+		llofstream os(file_name.c_str());
 
-	os << "Sample period(s)";
-	for (S32 frame = 1; frame <= frame_count; frame++)
-	{
-		frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
-		os << ", " << frame_time.value();
-	}
-	os << '\n';
+		os << std::setprecision(10);
 
+		LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
+		const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
 
-	typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
-	for (auto& it : trace_count::instance_snapshot())
-	{
-		std::ostringstream row;
-		row << std::setprecision(10);
+		F64Seconds frame_time;
 
-		row << it.getName();
-
-		const char* unit_label = it.getUnitLabel();
-		if(unit_label[0])
+		os << "Stat";
+		for (S32 frame = 1; frame <= frame_count; frame++)
 		{
-			row << "(" << unit_label << ")";
+			frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+			os << ", " << frame_time.value();
 		}
+		os << '\n';
 
-		S32 samples = 0;
-
+		os << "Sample period(s)";
 		for (S32 frame = 1; frame <= frame_count; frame++)
 		{
-			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
-			samples += recording.getSampleCount(it);
-			row << ", " << recording.getSum(it);
+			frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+			os << ", " << frame_time.value();
 		}
+		os << '\n';
 
-		row << '\n';
 
-		if (samples > 0)
+		typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
+		for (auto& it : trace_count::instance_snapshot())
 		{
-			os << row.str();
-		}
-	}
-
-	typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
+			std::ostringstream row;
+			row << std::setprecision(10);
 
-	for (auto& it : trace_event::instance_snapshot())
-	{
-		std::ostringstream row;
-		row << std::setprecision(10);
-		row << it.getName();
+			row << it.getName();
 
-		const char* unit_label = it.getUnitLabel();
-		if(unit_label[0])
-		{
-			row << "(" << unit_label << ")";
-		}
+			const char* unit_label = it.getUnitLabel();
+			if (unit_label[0])
+			{
+				row << "(" << unit_label << ")";
+			}
 
-		S32 samples = 0;
+			S32 samples = 0;
 
-		for (S32 frame = 1; frame <= frame_count; frame++)
-		{
-			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
-			samples += recording.getSampleCount(it);
-			F64 mean = recording.getMean(it);
-			if (llisnan(mean))
+			for (S32 frame = 1; frame <= frame_count; frame++)
 			{
-				row << ", n/a";
+				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+				samples += recording.getSampleCount(it);
+				row << ", " << recording.getSum(it);
 			}
-			else
+
+			row << '\n';
+
+			if (samples > 0)
 			{
-				row << ", " << mean;
+				os << row.str();
 			}
 		}
 
-		row << '\n';
+		typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
 
-		if (samples > 0)
+		for (auto& it : trace_event::instance_snapshot())
 		{
-			os << row.str();
-		}
-	}
+			std::ostringstream row;
+			row << std::setprecision(10);
+			row << it.getName();
 
-	typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
+			const char* unit_label = it.getUnitLabel();
+			if (unit_label[0])
+			{
+				row << "(" << unit_label << ")";
+			}
 
-	for (auto& it : trace_sample::instance_snapshot())
-	{
-		std::ostringstream row;
-		row << std::setprecision(10);
-		row << it.getName();
+			S32 samples = 0;
 
-		const char* unit_label = it.getUnitLabel();
-		if(unit_label[0])
-		{
-			row << "(" << unit_label << ")";
+			for (S32 frame = 1; frame <= frame_count; frame++)
+			{
+				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+				samples += recording.getSampleCount(it);
+				F64 mean = recording.getMean(it);
+				if (llisnan(mean))
+				{
+					row << ", n/a";
+				}
+				else
+				{
+					row << ", " << mean;
+				}
+			}
+
+			row << '\n';
+
+			if (samples > 0)
+			{
+				os << row.str();
+			}
 		}
 
-		S32 samples = 0;
+		typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
 
-		for (S32 frame = 1; frame <= frame_count; frame++)
+		for (auto& it : trace_sample::instance_snapshot())
 		{
-			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
-			samples += recording.getSampleCount(it);
-			F64 mean = recording.getMean(it);
-			if (llisnan(mean))
+			std::ostringstream row;
+			row << std::setprecision(10);
+			row << it.getName();
+
+			const char* unit_label = it.getUnitLabel();
+			if (unit_label[0])
+			{
+				row << "(" << unit_label << ")";
+			}
+
+			S32 samples = 0;
+
+			for (S32 frame = 1; frame <= frame_count; frame++)
 			{
-				row << ", n/a";
+				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+				samples += recording.getSampleCount(it);
+				F64 mean = recording.getMean(it);
+				if (llisnan(mean))
+				{
+					row << ", n/a";
+				}
+				else
+				{
+					row << ", " << mean;
+				}
 			}
-			else
+
+			row << '\n';
+
+			if (samples > 0)
 			{
-				row << ", " << mean;
+				os << row.str();
 			}
 		}
 
-		row << '\n'; 
-
-		if (samples > 0)
+		typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
+		for (auto& it : trace_mem::instance_snapshot())
 		{
-			os << row.str();
-		}
-	}
+			os << it.getName() << "(KiB)";
 
-	typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
-	for (auto& it : trace_mem::instance_snapshot())
-	{
-		os << it.getName() << "(KiB)";
+			for (S32 frame = 1; frame <= frame_count; frame++)
+			{
+				os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
+			}
 
-		for (S32 frame = 1; frame <= frame_count; frame++)
-		{
-			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
+			os << '\n';
 		}
 
-		os << '\n';
+		os.flush();
+		os.close();
+	}
+	catch (const std::ios_base::failure &e)
+	{
+		LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL;
 	}
-
-	os.flush();
-	os.close();
 }
 
 //-------------------------------------------------------------------------------------------------------------
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 71d906c936dbe2dc5ea5a9b29ab3e8ae872c3935..61d7514c5f9fee7686558c4ae81739b09ef312d0 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3581,11 +3581,6 @@ bool process_login_success_response()
 	}
 
 	// Request the map server url
-	// Non-agni grids have a different default location.
-	if (!LLGridManager::getInstance()->isInProductionGrid())
-	{
-		gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/");
-	}
 	std::string map_server_url = response["map-server-url"];
 	if(!map_server_url.empty())
 	{
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 47601f3195075f30c1b2ed9699b2213eb13f4224..d1ce4fedd4f98b8666ceb8634ff681f9eeb4bf11 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -48,8 +48,8 @@
 /// LLViewerAssetRequest
 ///----------------------------------------------------------------------------
 
- // There is also PoolSizeVAssetStorage value in setting that should mirror this name
-static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage";
+ // There is also PoolSizeAssetStorage value in setting that should mirror this name
+static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage";
 
 /**
  * @brief Local class to encapsulate asset fetch requests with a timestamp.
@@ -136,6 +136,14 @@ LLViewerAssetStorage::~LLViewerAssetStorage()
         // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later. 
         LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL);
     }
+
+    while (mCoroWaitList.size() > 0)
+    {
+        CoroWaitList &request = mCoroWaitList.front();
+        // Clean up pending downloads, delete request and trigger callbacks
+        removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE);
+        mCoroWaitList.pop_front();
+    }
 }
 
 // virtual 
@@ -362,6 +370,27 @@ void LLViewerAssetStorage::storeAssetData(
     }
 }
 
+void LLViewerAssetStorage::checkForTimeouts()
+{
+    LLAssetStorage::checkForTimeouts();
+
+    // Restore requests
+    LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
+    while (mCoroWaitList.size() > 0
+           && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+    {
+        CoroWaitList &request = mCoroWaitList.front();
+        
+        bool with_http = true;
+        bool is_temp = false;
+        LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp);
+
+        manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
+            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData));
+
+        mCoroWaitList.pop_front();
+    }
+}
 
 /**
  * @brief Allocate and queue an asset fetch request for the viewer
@@ -421,12 +450,20 @@ void LLViewerAssetStorage::queueRequestHttp(
     // This is the same as the current UDP logic - don't re-request a duplicate.
     if (!duplicate)
     {
-        bool with_http = true;
-        bool is_temp = false;
-        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
+        // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit
+        if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+        {
+            bool with_http = true;
+            bool is_temp = false;
+            LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
 
-        LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL,"LLViewerAssetStorage::assetRequestCoro",
-            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+            LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
+                boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+        }
+        else
+        {
+            mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data);
+        }
     }
 }
 
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index d4e6b02eb9ac48b08cf4d29b9dfba8d522aa6a25..8f37509ced855b8885b2013812e86dea6640e4ff 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -41,7 +41,7 @@ class LLViewerAssetStorage : public LLAssetStorage
 
 	~LLViewerAssetStorage();
 
-	virtual void storeAssetData(
+	void storeAssetData(
 		const LLTransactionID& tid,
 		LLAssetType::EType atype,
 		LLStoreAssetCallback callback,
@@ -50,9 +50,9 @@ class LLViewerAssetStorage : public LLAssetStorage
 		bool is_priority = false,
 		bool store_local = false,
 		bool user_waiting=FALSE,
-		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
-	
-	virtual void storeAssetData(
+		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override;
+
+	void storeAssetData(
 		const std::string& filename,
 		const LLTransactionID& tid,
 		LLAssetType::EType type,
@@ -61,16 +61,17 @@ class LLViewerAssetStorage : public LLAssetStorage
 		bool temp_file = false,
 		bool is_priority = false,
 		bool user_waiting=FALSE,
-		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
+		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override;
+
+    void checkForTimeouts() override;
 
 protected:
-	// virtual
 	void _queueDataRequest(const LLUUID& uuid,
 						   LLAssetType::EType type,
                            LLGetAssetCallback callback,
 						   void *user_data,
 						   BOOL duplicate,
-						   BOOL is_priority);
+						   BOOL is_priority) override;
 
     void queueRequestHttp(const LLUUID& uuid,
                           LLAssetType::EType type,
@@ -89,8 +90,35 @@ class LLViewerAssetStorage : public LLAssetStorage
 
     std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype);
 
-    void logAssetStorageInfo();
-    
+    void logAssetStorageInfo() override;
+
+    // Asset storage works through coroutines and coroutines have limited queue capacity
+    // This class is meant to temporary store requests when fiber's queue is full
+    class CoroWaitList
+    {
+    public:
+        CoroWaitList(LLViewerAssetRequest *req,
+            const LLUUID& uuid,
+            LLAssetType::EType atype,
+            LLGetAssetCallback &callback,
+            void *user_data)
+          : mRequest(req),
+            mId(uuid),
+            mType(atype),
+            mCallback(callback),
+            mUserData(user_data)
+        {
+        }
+
+        LLViewerAssetRequest* mRequest;
+        LLUUID mId;
+        LLAssetType::EType mType;
+        LLGetAssetCallback mCallback;
+        void *mUserData;
+    };
+    typedef std::list<CoroWaitList> wait_list_t;
+    wait_list_t mCoroWaitList;
+
     std::string mViewerAssetUrl;
     S32 mAssetCoroCount;
     S32 mCountRequests;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index c2aba825cc8256dbafec88f919779a2cdc7b5360..68fab9f161d0a325f8e94668bad558fa329287b1 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -5516,7 +5516,7 @@ class LLToolsSelectNextPartFace : public view_listener_t
                         new_te = to_select->getNumTEs() - 1;
                     }
                 }
-                LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE);
+                LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te);
             }
             else
             {
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 9e579478e3b3904f1f7b432e168eb7c8f74dcda0..33580a292b378b0b7f255b2550400d905792ccd1 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -130,7 +130,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "https://secondlife.aditi.lindenlab.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
 				  SL_UPDATE_QUERY_URL,
-				  "https://my.aditi.lindenlab.com/",
+				  "https://my.secondlife-beta.com/",
 				  "Aditi");
 
 	LLSD other_grids;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 8f7f3622d08fd986dcbdc90ccc9b7e4bf946c057..4b84a794f647d536b9060d24e41c5b757b5ea881 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4936,22 +4936,78 @@ void LLViewerObject::refreshBakeTexture()
 	}
 }
 
+void LLViewerObject::updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture)
+{
+    // Objects getting non-alpha texture and alpha mask can result in graphical bugs, like white or red alphas.
+    // To resolve the issue this function provides image format to material and based on format material's
+    // getDiffuseAlphaModeRender() function will decide what value to provide to render
+    //
+    // Unfortunately LLMaterial has no access to diffuse image, so we have to set this data in LLViewerObject
+    // regardles of object being used/seen or frequency of image-updates.
+    mat->setDiffuseBaked(baked_texture);
+
+    if (!baked_texture)
+    {
+        if (imagep->isMissingAsset())
+        {
+            mat->setDiffuseFormatPrimary(0);
+        }
+        else if (0 == imagep->getPrimaryFormat())
+        {
+            // We don't have information about this texture, wait for it
+            mWaitingTextureInfo.insert(uuid_material_mmap_t::value_type(imagep->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
+            // Temporary assume RGBA image
+            mat->setDiffuseFormatPrimary(GL_RGBA);
+        }
+        else
+        {
+            mat->setDiffuseFormatPrimary(imagep->getPrimaryFormat());
+        }
+    }
+}
+
+S32 LLViewerObject::setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep)
+{
+    LLUUID new_id = imagep->getID();
+    S32 retval = LLPrimitive::setTETexture(te, new_id);
+
+    LLTextureEntry* tep = getTE(te);
+    LLUUID old_image_id = tep->getID();
+
+    LLViewerTexture* baked_texture = getBakedTextureForMagicId(new_id);
+    mTEImages[te] = baked_texture ? baked_texture : imagep;
+    updateAvatarMeshVisibility(new_id, old_image_id);
+
+    LLMaterial* mat = tep->getMaterialParams();
+    if (mat)
+    {
+        // Don't update format from texture (and don't shedule one) if material has no alpha mode set,
+        // just assume RGBA format, format will get updated with setTEMaterialParams call if mode changes
+        if (mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
+        {
+            bool baked = baked_texture != NULL;
+            updateDiffuseMatParams(te, mat, imagep, baked);
+        }
+        else
+        {
+            mat->setDiffuseFormatPrimary(GL_RGBA);
+        }
+    }
+
+    setChanged(TEXTURE);
+    if (mDrawable.notNull())
+    {
+        gPipeline.markTextured(mDrawable);
+    }
+
+    return retval;
+}
+
 void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
 {
 	if (mTEImages[te] != imagep)
 	{
-		LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null;
-		
-		LLPrimitive::setTETexture(te, imagep->getID());
-
-		LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID());
-		mTEImages[te] = baked_texture ? baked_texture : imagep;
-		updateAvatarMeshVisibility(imagep->getID(), old_image_id);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull())
-		{
-			gPipeline.markTextured(mDrawable);
-		}
+        setDiffuseImageAndParams(te, imagep);
 	}
 }
 
@@ -4963,15 +5019,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
 	if (uuid != getTE(te)->getID() ||
 		uuid == LLUUID::null)
 	{
-		retval = LLPrimitive::setTETexture(te, uuid);
-		LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid);
-		mTEImages[te] = baked_texture ? baked_texture : image;
-		updateAvatarMeshVisibility(uuid,old_image_id);
-		setChanged(TEXTURE);
-		if (mDrawable.notNull())
-		{
-			gPipeline.markTextured(mDrawable);
-		}
+		retval = setDiffuseImageAndParams(te, image);
 	}
 	return retval;
 }
@@ -5268,6 +5316,29 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
 		return 0;
 	}
 
+    if (pMaterialParams.notNull()
+        && pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
+    {
+        // Don't update if no alpha is set. If alpha changes, this function will run again,
+        // no point in sheduling additional texture callbacks (in updateDiffuseMatParams)
+        LLTextureEntry* tex_entry = getTE(te);
+        bool is_baked = tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID());
+
+        LLViewerTexture *img_diffuse = getTEImage(te);
+        llassert(NULL != img_diffuse);
+
+        if (NULL != img_diffuse)
+        {
+            // Will modify alpha mask provided to renderer to fit image
+            updateDiffuseMatParams(te, pMaterialParams.get(), img_diffuse, is_baked);
+        }
+        else
+        {
+            LLMaterial *mat = pMaterialParams.get(); // to avoid const
+            mat->setDiffuseFormatPrimary(0);
+        }
+    }
+
 	retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
 #if SHOW_DEBUG
 	LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
@@ -5282,6 +5353,84 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
 	return retval;
 }
 
+bool LLViewerObject::notifyAboutCreatingTexture(LLViewerTexture *texture)
+{
+    // Confirmation about texture creation, check wait-list
+    // and make changes, or return false
+
+    std::pair<uuid_material_mmap_t::iterator, uuid_material_mmap_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
+
+    bool refresh_materials = false;
+
+    // RGB textures without alpha channels won't work right with alpha,
+    // we provide format to material for material to decide when to drop alpha
+    for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it)
+    {
+        LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+        if (cur_material.notNull()
+            && LLRender::DIFFUSE_MAP == range_it->second.map)
+        {
+            U32 format = texture->getPrimaryFormat();
+            if (format != cur_material->getDiffuseFormatPrimary())
+            {
+                cur_material->setDiffuseFormatPrimary(format);
+                refresh_materials = true;
+            }
+        }
+    } //for
+
+    if (refresh_materials)
+    {
+        LLViewerObject::refreshMaterials();
+    }
+
+    //clear wait-list
+    mWaitingTextureInfo.erase(range.first, range.second);
+
+    return refresh_materials;
+}
+
+bool LLViewerObject::notifyAboutMissingAsset(LLViewerTexture *texture)
+{
+    // When waiting information about texture it turned out to be missing.
+    // Confirm the state, update values accordingly
+    std::pair<uuid_material_mmap_t::iterator, uuid_material_mmap_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
+    if (range.first == range.second) return false;
+
+    bool refresh_materials = false;
+
+    for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it)
+    {
+        LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+        if (cur_material.isNull())
+            continue;
+
+        if (range_it->second.map == LLRender::DIFFUSE_MAP)
+        {
+            LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
+            if (cur_material.notNull()
+                && LLRender::DIFFUSE_MAP == range_it->second.map)
+            {
+                if (0 != cur_material->getDiffuseFormatPrimary())
+                {
+                    cur_material->setDiffuseFormatPrimary(0);
+                    refresh_materials = true;
+                }
+            }
+        }
+    } //for
+
+    if (refresh_materials)
+    {
+        LLViewerObject::refreshMaterials();
+    }
+
+    //clear wait-list
+    mWaitingTextureInfo.erase(range.first, range.second);
+
+    return refresh_materials;
+}
+
 void LLViewerObject::refreshMaterials()
 {
 	setChanged(TEXTURE);
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index f081e379210a3635671b3727b6765a367789581c..ecd30b6e42e4dbc7266e18925eb651097bc0d9ca 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -816,7 +816,12 @@ class LLViewerObject
 	void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
 	void deleteParticleSource();
 	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
-	
+
+    // Helper function to modify alpha mask provided to render according to image (ex: RGB image will drop alpha mask)
+    void updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture);
+    // Shared part of code from setTEImage and setTETextureCore
+    S32 setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep);
+
 private:
 	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
 	void deleteTEImages(); // correctly deletes list of images
@@ -949,10 +954,27 @@ class LLViewerObject
 
     LLJointRiggingInfoTab mJointRiggingInfoTab;
 
+    bool notifyAboutCreatingTexture(LLViewerTexture *texture);
+    bool notifyAboutMissingAsset(LLViewerTexture *texture);
+
 private:
 	LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
 	EObjectUpdateType	mLastUpdateType;
 	BOOL	mLastUpdateCached;
+
+    struct material_info
+    {
+        LLRender::eTexIndex map;
+        U8 te;
+
+        material_info(LLRender::eTexIndex map_, U8 te_)
+            : map(map_)
+            , te(te_)
+        {}
+    };
+
+    typedef std::multimap<LLUUID, material_info> uuid_material_mmap_t;
+    uuid_material_mmap_t mWaitingTextureInfo;
 };
 
 ///////////////////
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 991342483927ace4010b4bf4919efcda27154bce..eec80faf356d7b1008082e702a6b25e56dbaf98e 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2353,7 +2353,6 @@ void LLViewerWindow::shutdownGL()
 LLViewerWindow::~LLViewerWindow()
 {
 	LL_INFOS() << "Destroying Window" << LL_ENDL;
-	gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes
 	destroyWindow();
 
 	delete mDebugText;
@@ -2444,6 +2443,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 		// round up when converting coordinates to make sure there are no gaps at edge of window
 		LLView::sForceReshape = display_scale_changed;
 		mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
+        if (display_scale_changed)
+        {
+            // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass()
+            LLPanelLogin::reshapePanel();
+        }
 		LLView::sForceReshape = FALSE;
 
 		// clear font width caches
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 9d868c6874bfaf06804cd708f7ce56ae5598380b..2f62675108ee3d6599861dba588a4c43f863266e 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -180,6 +180,13 @@ void LLVoiceClient::terminate()
 {
 	if (mVoiceModule) mVoiceModule->terminate();
 	mVoiceModule = NULL;
+    m_servicePump = NULL;
+
+    // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it
+    if (LLSpeakerVolumeStorage::instanceExists())
+    {
+        LLSpeakerVolumeStorage::deleteSingleton();
+    }
 }
 
 const LLVoiceVersionInfo LLVoiceClient::getVersion()
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 22037f6e7b0d4d28c9d304381ca446a27032189e..2f201c3201caff35130ab657c168e2b859807b40 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -394,7 +394,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
 void LLVivoxVoiceClient::init(LLPumpIO *pump)
 {
 	// constructor will set up LLVoiceClient::getInstance()
-	LLVivoxVoiceClient::getInstance()->mPump = pump;
+	mPump = pump;
 
 //     LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
 //         boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
@@ -422,6 +422,7 @@ void LLVivoxVoiceClient::terminate()
 	}
 
     sShuttingDown = true;
+    mPump = NULL;
 }
 
 //---------------------------------------------------
@@ -960,10 +961,15 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
 
     llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
 
-    while (!mPump)
-    {   // Can't do this until we have the pump available.
+    while (!mPump && !sShuttingDown)
+    {   // Can't use the pump until we have it available.
         llcoro::suspend();
     }
+
+    if (sShuttingDown)
+    {
+        return false;
+    }
     
     // MBW -- Note to self: pumps and pipes examples in
     //  indra/test/io.cpp
@@ -976,8 +982,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
     readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket)));
     readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser()));
 
+
     mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS);
 
+
     //---------------------------------------------------------------------
     llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
 
@@ -1000,6 +1008,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
         // *TODO* Pump a message for wake up.
         llcoro::suspend();
     }
+    
+    if (sShuttingDown)
+    {
+        return false;
+    }
 
     std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest");
 
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index fff5c6436fc5ce2d81ef6e5b872dfc4c190412f6..f659dc798aff73f35659dc27bd5bb0e3324d13c1 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -45,6 +45,8 @@
 #include "llviewertexturelist.h"
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
+#include "llvolumemgr.h"
+#include "llvovolume.h"
 #include "llworld.h"
 #include "noise.h"
 #include "pipeline.h"
@@ -85,6 +87,9 @@ LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *region
 	mFrameCount = 0;
 	mWind = mRegionp->mWind.getVelocity(getPositionRegion());
 	mTrunkLOD = 0;
+
+	// if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels
+	llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS);
 }
 
 
@@ -346,8 +351,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
 		return;
 	}
 	
-	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ;
+	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled
 	F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor;
+	F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f);
+	F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter
+	F32 sz = mBillboardScale * mBillboardRatio * diameter;
 
 	for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++)
 	{
@@ -356,7 +364,14 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
 			trunk_LOD = j;
 			break;
 		}
-	} 
+	}
+
+    F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance;
+    S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality
+
+    // for trunk_LOD lower value means better quality, but both trunk_LOD and cur_detail have 4 levels
+    trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1);
+    trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS);
 
 	if (mReferenceBuffer.isNull())
 	{
@@ -409,8 +424,9 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
 	LLVector3 lookAt = center - viewer_pos_agent;
 	F32 dist = lookAt.normVec() ;	
 	F32 cos_angle_to_view_dir = lookAt * viewerCamera.getXAxis() ;
-	
-	F32 range = dist - getMinScale()/2;
+	F32 radius = getScale().length()*0.5f;
+	F32 range = dist - radius;
+
 	if (range < F_ALMOST_ZERO || isHUDAttachment())		// range == zero
 	{
 		mAppAngle = 180.f;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 33d9272d739a3316c3a592efef03e8be1496f2cc..d2fce7933d356fc04c95f86c1e754a6f8656a8d9 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2349,252 +2349,15 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 	return res;
 }
 
-bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{ //Ok, here we have confirmation about texture creation, check our wait-list
-  //and make changes, or return false
-
-	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-
-	typedef std::map<U8, LLMaterialPtr> map_te_material;
-	map_te_material new_material;
-
-	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
-	{
-		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-		if (cur_material.isNull())
-			continue;
-
-		//here we just interesting in DIFFUSE_MAP only!
-		if(LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat())
-		{ //ok let's check the diffuse mode
-			switch(cur_material->getDiffuseAlphaMode())
-			{
-			case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
-			case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
-			case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
-				{ //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-
-					LLMaterialPtr mat = NULL;
-					map_te_material::iterator it = new_material.find(range_it->second.te);
-					if(new_material.end() == it) {
-						mat = new LLMaterial(cur_material->asLLSD());
-						new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-					} else {
-						mat = it->second;
-					}
-
-					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-
-				} break;
-			} //switch
-		} //if
-	} //for
-
-	//setup new materials
-	auto& matMgr = LLMaterialMgr::instance();
-	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
-	{
-		// These are placeholder materials, they shouldn't be sent to server
-		matMgr.setLocalMaterial(getRegion()->getRegionID(), it->second);
-		LLViewerObject::setTEMaterialParams(it->first, it->second);
-	}
-
-	//clear wait-list
-	mWaitingTextureInfo.erase(range.first, range.second);
-
-	return 0 != new_material.size();
-}
-
-bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
-{ //Ok, here if we wait information about texture and it's missing
-  //then depending from the texture map (diffuse, normal, or specular)
-  //make changes in material and confirm it. If not return false.
-	std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-	if(range.first == range.second) return false;
-
-	typedef std::map<U8, LLMaterialPtr> map_te_material;
-	map_te_material new_material;
-	
-	for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
-	{
-		LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-		if (cur_material.isNull())
-			continue;
-
-		switch(range_it->second.map)
-		{
-		case LLRender::DIFFUSE_MAP:
-			{
-				if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
-				{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-					LLMaterialPtr mat = NULL;
-					map_te_material::iterator it = new_material.find(range_it->second.te);
-					if(new_material.end() == it) {
-						mat = new LLMaterial(cur_material->asLLSD());
-						new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-					} else {
-						mat = it->second;
-					}
-
-					mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-				}
-			} break;
-		case LLRender::NORMAL_MAP:
-			{ //missing texture => reset material texture id
-				LLMaterialPtr mat = NULL;
-				map_te_material::iterator it = new_material.find(range_it->second.te);
-				if(new_material.end() == it) {
-					mat = new LLMaterial(cur_material->asLLSD());
-					new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-				} else {
-					mat = it->second;
-				}
-
-				mat->setNormalID(LLUUID::null);
-			} break;
-		case LLRender::SPECULAR_MAP:
-			{ //missing texture => reset material texture id
-				LLMaterialPtr mat = NULL;
-				map_te_material::iterator it = new_material.find(range_it->second.te);
-				if(new_material.end() == it) {
-					mat = new LLMaterial(cur_material->asLLSD());
-					new_material.insert(map_te_material::value_type(range_it->second.te, mat));
-				} else {
-					mat = it->second;
-				}
-
-				mat->setSpecularID(LLUUID::null);
-			} break;
-		case LLRender::NUM_TEXTURE_CHANNELS:
-				//nothing to do, make compiler happy
-			break;
-		} //switch
-	} //for
-
-	//setup new materials
-	auto& matMgr = LLMaterialMgr::instance();
-	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
-	{
-		matMgr.setLocalMaterial(getRegion()->getRegionID(), it->second);
-		LLViewerObject::setTEMaterialParams(it->first, it->second);
-	}
-
-	//clear wait-list
-	mWaitingTextureInfo.erase(range.first, range.second);
-
-	return 0 != new_material.size();
-}
-
 S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
 {
-	LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
-
-	if(pMaterialParams)
-	{ //check all of them according to material settings
-
-		LLViewerTexture *img_diffuse = getTEImage(te);
-		LLViewerTexture *img_normal = getTENormalMap(te);
-		LLViewerTexture *img_specular = getTESpecularMap(te);
-
-		llassert(NULL != img_diffuse);
-
-		LLMaterialPtr new_material = NULL;
-
-		//diffuse
-		if(NULL != img_diffuse)
-		{ //guard
-			if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
-			{ //ok here we don't have information about texture, let's belief and leave material settings
-			  //but we remember this case
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
-			}
-			else
-			{
-				bool bSetDiffuseNone = false;
-				if(img_diffuse->isMissingAsset())
-				{
-					bSetDiffuseNone = true;
-				}
-				else
-				{
-					switch(pMaterialParams->getDiffuseAlphaMode())
-					{
-					case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
-					case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
-					case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
-						{ //all of them modes available only for 32 bit textures
-							LLTextureEntry* tex_entry = getTE(te);
-							bool bIsBakedImageId = false;
-							if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()))
-							{
-								bIsBakedImageId = true;
-							}
-							if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId)
-							{
-								bSetDiffuseNone = true;
-							}
-						} break;
-					}
-				} //else
-
-
-				if(bSetDiffuseNone)
-				{ //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-					new_material = new LLMaterial(pMaterialParams->asLLSD());
-					new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-				}
-			}
-		}
-
-		//normal
-		if(LLUUID::null != pMaterialParams->getNormalID())
-		{
-			if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
-			{
-				if(!new_material) {
-					new_material = new LLMaterial(pMaterialParams->asLLSD());
-				}
-				new_material->setNormalID(LLUUID::null);
-			}
-			else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
-			{ //ok here we don't have information about texture, let's belief and leave material settings
-				//but we remember this case
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
-			}
-
-		}
-
-
-		//specular
-		if(LLUUID::null != pMaterialParams->getSpecularID())
-		{
-			if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
-			{
-				if(!new_material) {
-					new_material = new LLMaterial(pMaterialParams->asLLSD());
-				}
-				new_material->setSpecularID(LLUUID::null);
-			}
-			else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
-			{ //ok here we don't have information about texture, let's belief and leave material settings
-				//but we remember this case
-				mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
-			}
-		}
-
-		if(new_material) {
-			pMaterial = new_material;
-			LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial);
-		}
-	}
-
 #if SHOW_DEBUG
 	S32 res = 
 #endif
-		LLViewerObject::setTEMaterialParams(te, pMaterial);
+		LLViewerObject::setTEMaterialParams(te, pMaterialParams);
 
 #if SHOW_DEBUG
-	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res
+	LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
 							 << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
 							 << LL_ENDL;
 #endif
@@ -4748,7 +4511,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
 					LLMaterial* mat = te->getMaterialParams();
 					if (mat)
 					{
-						U8 mode = mat->getDiffuseAlphaMode();
+						U8 mode = mat->getDiffuseAlphaModeRender();
 
 						if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE
 							|| mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE
@@ -5383,7 +5146,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 			}
 
 			draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
-			draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+			draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaModeRender();
 			draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
 		}
 		else 
@@ -5732,7 +5495,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 						if (mat && LLPipeline::sRenderDeferred)
 						{
-							U8 alpha_mode = mat->getDiffuseAlphaMode();
+							U8 alpha_mode = mat->getDiffuseAlphaModeRender();
 
 							bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
 								(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
@@ -5761,7 +5524,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						else if (mat)
 						{							
 							bool is_alpha = type == LLDrawPool::POOL_ALPHA;
-							U8 mode = mat->getDiffuseAlphaMode();
+							U8 mode = mat->getDiffuseAlphaModeRender();
 							bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
 												mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
 							
@@ -6654,7 +6417,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 			bool can_be_shiny = true;
 			if (mat)
 			{
-				U8 mode = mat->getDiffuseAlphaMode();
+				U8 mode = mat->getDiffuseAlphaModeRender();
 				can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
 								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
 			}
@@ -6676,7 +6439,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 				//
 				if (te->getFullbright())
 				{
-					if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+					if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 					{
 						if (opaque)
 						{
@@ -6761,7 +6524,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 			}
 			else if (mat)
 			{
-				U8 mode = mat->getDiffuseAlphaMode();
+				U8 mode = mat->getDiffuseAlphaModeRender();
 
                 is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND));
 
@@ -6860,7 +6623,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 				}
 				else if (fullbright || bake_sunlight)
 				{ //fullbright
-					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+					if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 					{
 						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
 					}
@@ -6882,7 +6645,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 					else
 					{ //all around simple
 						llassert(mask & LLVertexBuffer::MAP_NORMAL);
-						if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+						if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
 						{ //material alpha mask can be respected in non-deferred
 							registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
 						}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 8296e2f74a883f753c539bdd4995acaf410472f2..4691a5f98c232c7faa8eecc530875ae481f72e59 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -457,26 +457,6 @@ class LLVOVolume final : public LLViewerObject
 	static S32 sNumLODChanges;
 
 	friend class LLVolumeImplFlexible;
-
-public:
-	bool notifyAboutCreatingTexture(LLViewerTexture *texture);
-	bool notifyAboutMissingAsset(LLViewerTexture *texture);
-
-private:
-	struct material_info 
-	{
-		LLRender::eTexIndex map;
-		U8 te;
-
-		material_info(LLRender::eTexIndex map_, U8 te_)
-			: map(map_)
-			, te(te_)
-		{}
-	};
-
-	typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
-	mmap_UUID_MAP_t	mWaitingTextureInfo;
-
 };
 
 #endif // LL_LLVOVOLUME_H
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2df72d4ffe4236844543316dfc70a2090c23c20f..3a9cbdaa0288888c71551a3ddeb15d23e17b61c7 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1735,7 +1735,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
 
 	if (alpha && mat)
 	{
-		switch (mat->getDiffuseAlphaMode())
+		switch (mat->getDiffuseAlphaModeRender())
 		{
 			case 1:
 				alpha = true; // Material's alpha mode is set to blend.  Toss it into the alpha draw pool.
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 2f8be11fdff681ee6ed25eb887e1085ac044905f..4f2bec9b179df35127ef7e6a8967306b65b41b6c 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -339,6 +339,9 @@
     <color
      name="ContextSilhouetteColor"
      reference="EmphasisColor" />
+    <color
+     name="ConversationFriendColor"
+     value="0.42 0.85 0.71 1" />
     <color
      name="DefaultHighlightDark"
      reference="White_10" />
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
index 49be4290c702ddbf5a15360ed537ae981cfdb6ed..1f7d52dbf5b504c6c4d4df0245add2dd998a91f4 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
@@ -32,6 +32,10 @@
      name="no_transfer_text">
         (no transfer)
     </floater.string>
+    <floater.string
+      name="mupliple_selected">
+        Mupliple selection
+    </floater.string>
     <scroll_list
      background_visible="true"
      draw_border="false"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 2fc744d002a57a8f1d6e70769fe6c542c5e8143b..b00b6717eb469594cf932b8798d75ec1d67c044d 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -477,6 +477,36 @@
                  right="-1">
                     <layout_panel
                      name="input_editor_layout_panel">
+                        <avatar_icon
+                         follows="left|bottom"
+                         name="avatar_icon"
+                         height="20"
+                         default_icon_name="Generic_Person"
+                         layout="topleft"
+                         left="3"
+                         bottom="-9"
+                         visible="false"
+                         width="20" />
+                        <group_icon
+                         follows="left|bottom"
+                         name="group_chat_icon"
+                         height="20"
+                         default_icon_name="Generic_Group"
+                         layout="topleft"
+                         left="3"
+                         bottom="-9"
+                         visible="false"
+                         width="20" />
+                        <icon
+                         follows="left|bottom"
+                         height="20"
+                         image_name="Nearby_chat_icon"
+                         layout="topleft"
+                         left="3"
+                         bottom="-9"
+                         name="nearby_chat_icon"
+                         visible="false"
+                         width="20"/>
                         <chat_editor
                          layout="topleft"
                          expand_lines_count="5"
@@ -490,7 +520,7 @@
                          spellcheck="true"
                          tab_group="3"
                          bottom="-4"
-                         left="3"
+                         left_pad="5"
                          right="-1"
                          wrap="true" />
                     </layout_panel>
diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
index 322e34272c09c3a4153ac3c985b404bdb9820267..84e0b489d0eff34783b40f15a69b7338f094162e 100644
--- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
@@ -6,6 +6,7 @@
  layout="topleft"
  name="publish_classified"
  title="Publishing Classified"
+ help_topic="profile_edit_classified"
  width="320">
     <text
      top="20"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9edacd7c1b09f87dc68e3e15f28bc4729378a42d..6181f951810330dc4c4736a69dd6b4ac0ba75d23 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4148,6 +4148,8 @@ Finished download of raw terrain file to:
 [DOWNLOAD_PATH].
   </notification>
 
+  <!-- RequiredUpdate does not display release notes URL because we don't get
+       that from login.cgi's login failure message. -->
   <notification
    icon="alertmodal.tga"
    name="RequiredUpdate"
@@ -4165,6 +4167,8 @@ Please download from https://www.alchemyviewer.org/pages/downloads.html
    name="PauseForUpdate"
    type="alertmodal">
 Version [VERSION] is required for login.
+Release notes: [URL]
+
 Click OK to download and install.
     <tag>confirm</tag>
     <usetemplate
@@ -4177,6 +4181,8 @@ Click OK to download and install.
    name="OptionalUpdateReady"
    type="alertmodal">
 Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
+
 Click OK to install.
     <tag>confirm</tag>
     <usetemplate
@@ -4189,6 +4195,8 @@ Click OK to install.
    name="PromptOptionalUpdate"
    type="alertmodal">
 Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
+
 Proceed?
     <tag>confirm</tag>
     <usetemplate
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 41036ea54d8e36885a5a567c06fa79202aa2fc22..97586277e86dcdaf53238b28bfaaf5b1f1d4d64a 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2308,6 +2308,7 @@ For AI Character: Get the closest navigable point to the point provided.
 	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
 	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
 	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
+	<string name="MarketplaceNoListing">You have no listings yet.</string>
 	<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>
 	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
 	<string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string>
@@ -3715,10 +3716,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
   Also there are some other places where "generic" is used.
   So, let add string with name="generic" with the same value as "generic_request_error" -->
   <string name="generic">
-    Error making request, please try again later.
+    Please close and reopen the conversation, or relog and try again.
   </string>
   <string name="generic_request_error">
-    Error making request, please try again later.
+    Please close and reopen the conversation, or relog and try again.
   </string>
   <string name="insufficient_perms_error">
     You do not have sufficient permissions.
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 16eda7485d11889ebb4740ed701b10ba5815b444..64521ecea3da627212401790d9e84fc6b3a6341d 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -41,6 +41,7 @@
 #include "../test/lltut.h"
 #include "llevents.h"
 #include "llnotificationsutil.h"
+#include "lltrans.h"
 
 #if defined(LL_WINDOWS)
 #pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
@@ -77,6 +78,11 @@ void LLViewerWindow::setShowProgress(BOOL show) {}
 LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }
 
 LLViewerWindow* gViewerWindow;
+
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
+{
+    return std::string("test_trans");
+}
 	
 class LLLogin::Impl
 {