diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6d296d7a24cd416f33970eca5d76f0cdbdcf18ce
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,17 @@
+repos:
+  - repo: https://bitbucket.org/lindenlab/git-hooks.git 
+    rev: v1.0.0-beta2
+    hooks:
+      - id: opensource-license
+      - id: jira-issue 
+      - id: llsd
+      - id: no-trigraphs
+      - id: copyright
+      - id: end-of-file
+        files: \.(cpp|c|h|py|glsl|cmake|txt)$
+        exclude: language.txt
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v2.5.0
+    hooks:
+      - id: check-xml
+      - id: mixed-line-ending
diff --git a/autobuild.xml b/autobuild.xml
index 64168b0a87d3158b514835fe744150d81b0f255c..0ab120f50e035a18db54c7c4c696d8188bdc7bed 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2201,18 +2201,18 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>95cb09a712b7b61e992fe68ab7bf8c72</string>
+              <string>d6e7ab8483c348f223fd24028e27a52f</string>
               <key>hash_algorithm</key>
               <string>md5</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/92744/837149/llca-202201010217.567162-common-567162.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/93933/844890/llca-202202010217.567974-common-567974.tar.bz2</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
         <key>version</key>
-        <string>202201010217.567162</string>
+        <string>202202010217.567974</string>
       </map>
       <key>llphysicsextensions_source</key>
       <map>
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index d35f2499730a14a2ed159388e697d78f9db89e62..e0ebbb76bd30770759ba12c201e4b29549aa74d0 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1402,6 +1402,15 @@ bool LLAudioSource::setupChannel()
 	return true;
 }
 
+void LLAudioSource::stop()
+{
+    play(LLUUID::null);
+    if (mCurrentDatap)
+    {
+        // always reset data if something wants us to stop
+        mCurrentDatap = nullptr;
+    }
+}
 
 bool LLAudioSource::play(const LLUUID &audio_uuid)
 {
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index 577b36d667f895fe2535a6750ed46b14a31f156f..b5fd4c27a19d9954ec85d47233e96eba247baa6d 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -304,7 +304,13 @@ class LLAudioSource
 	LLAudioBuffer *getCurrentBuffer();
 
 	bool setupChannel();
-	bool play(const LLUUID &audio_id);	// Start the audio source playing
+
+    // Stop the audio source, reset audio id even if muted
+    void stop();
+
+    // Start the audio source playing,
+    // takes mute into account to preserve previous id if nessesary
+    bool play(const LLUUID &audio_id);
 
 	bool hasPendingPreloads() const;	// Has preloads that haven't been done yet
 
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 75fc0fec99d19942c8859130c6f29b7160d1da4e..c2d353b0fc9b89ee44bfb43335bb4fdabf936851 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -249,14 +249,25 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
     // protected_fixedsize_stack sets a guard page past the end of the new
     // stack so that stack underflow will result in an access violation
     // instead of weird, subtle, possibly undiagnosed memory stomps.
-    boost::fibers::fiber newCoro(boost::fibers::launch::dispatch,
-                                 std::allocator_arg,
-                                 boost::fibers::protected_fixedsize_stack(mStackSize),
-                                 [this, &name, &callable](){ toplevel(name, callable); });
-    // You have two choices with a fiber instance: you can join() it or you
-    // can detach() it. If you try to destroy the instance before doing
-    // either, the program silently terminates. We don't need this handle.
-    newCoro.detach();
+
+    try
+    {
+        boost::fibers::fiber newCoro(boost::fibers::launch::dispatch,
+            std::allocator_arg,
+            boost::fibers::protected_fixedsize_stack(mStackSize),
+            [this, &name, &callable]() { toplevel(name, callable); });
+
+        // You have two choices with a fiber instance: you can join() it or you
+        // can detach() it. If you try to destroy the instance before doing
+        // either, the program silently terminates. We don't need this handle.
+        newCoro.detach();
+    }
+    catch (std::bad_alloc&)
+    {
+        // Out of memory on stack allocation?
+        LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL;
+    }
+
     return name;
 }
 
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 995356dc520197e4e5d8a3fad20f13229621a42f..067b5e6fbc9737f88d655268d051cd42107d9bfa 100644
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -101,7 +101,7 @@ void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value)
     }
 
     // Drill down to where we should store 'value'.
-    llsd::drill(dest, path) = value;
+    llsd::drill_ref(dest, path) = value;
 }
 
 } // anonymous
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index eb3a96b1333d6d6902ea277b5c46ed60905f5829..fc10fcece34cfd5d34687480ce64331228d68ae7 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -29,6 +29,7 @@
 #include "linden_common.h"
 
 #include "llsdutil.h"
+#include <sstream>
 
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
@@ -862,7 +863,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
 namespace llsd
 {
 
-LLSD& drill(LLSD& blob, const LLSD& rawPath)
+LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
 {
     // Treat rawPath uniformly as an array. If it's not already an array,
     // store it as the only entry in one. (But let's say Undefined means an
@@ -917,9 +918,9 @@ LLSD& drill(LLSD& blob, const LLSD& rawPath)
 
 LLSD drill(const LLSD& blob, const LLSD& path)
 {
-    // non-const drill() does exactly what we want. Temporarily cast away
+    // drill_ref() does exactly what we want. Temporarily cast away
     // const-ness and use that.
-    return drill(const_cast<LLSD&>(blob), path);
+    return drill_ref(const_cast<LLSD&>(blob), path);
 }
 
 } // namespace llsd
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 8678ca97f2e9ac7b75c0f468af9bf5c90b44f8cc..1321615805bfec449bedcd91b464962a67ce1fef 100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
@@ -184,10 +184,10 @@ namespace llsd
  *   - Anything else is an error.
  *
  * By implication, if path.isUndefined() or otherwise equivalent to an empty
- * LLSD::Array, drill() returns 'blob' as is.
+ * LLSD::Array, drill[_ref]() returns 'blob' as is.
  */
 LLSD  drill(const LLSD& blob, const LLSD& path);
-LLSD& drill(      LLSD& blob, const LLSD& path);
+LLSD& drill_ref(  LLSD& blob, const LLSD& path);
 
 }
 
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 8df818559d60bace84998d88d755c3288893b066..cdc1d83b591a096d840a8cfdcbe6863ea77045dc 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -195,18 +195,6 @@ LLOSInfo::LLOSInfo() :
 		GetSystemInfo(&si); //if it fails get regular system info 
 	//(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load)
 
-	//msdn microsoft finds 32 bit and 64 bit flavors this way..
-	//http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors
-	//of windows than this code does (in case it is needed for the future)
-	if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit
-	{
-		mOSStringSimple += "64-bit ";
-	}
-	else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
-	{
-		mOSStringSimple += "32-bit ";
-	}
-
 	// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
 	OSVERSIONINFOEX osvi;
 	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
@@ -253,9 +241,21 @@ LLOSInfo::LLOSInfo() :
             // Query WMI's Win32_OperatingSystem for OS string. Slow
             // and likely to return 'compatibility' string.
             // Check presence of dlls/libs or may be their version.
-            mOSStringSimple = "Microsoft Windows 10/11";
+            mOSStringSimple = "Microsoft Windows 10/11 ";
         }
-	}
+    }
+
+    //msdn microsoft finds 32 bit and 64 bit flavors this way..
+    //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors
+    //of windows than this code does (in case it is needed for the future)
+    if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit
+    {
+        mOSStringSimple += "64-bit ";
+    }
+    else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
+    {
+        mOSStringSimple += "32-bit ";
+    }
 
 	mOSString = mOSStringSimple;
 	if (mBuild > 0)
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 13b65dfaa04278a4633cce5fddb061fe9e2aa909..411d76adb2f6fe9db01b83517e55d00558bd85d3 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5745,7 +5745,16 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
 		resizeIndices(grid_size*grid_size*6);
 		if (!volume->isMeshAssetLoaded())
 		{
-			mEdge.resize(grid_size*grid_size * 6);
+            S32 size = grid_size * grid_size * 6;
+            try
+            {
+                mEdge.resize(size);
+            }
+            catch (std::bad_alloc&)
+            {
+                LL_WARNS("LLVOLUME") << "Resize of mEdge to " << size << " failed" << LL_ENDL;
+                return false;
+            }
 		}
 
 		U16* out = mIndices;
@@ -6554,7 +6563,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
 
 		if (!volume->isMeshAssetLoaded())
 		{
-			mEdge.resize(num_indices);
+            try
+            {
+                mEdge.resize(num_indices);
+            }
+            catch (std::bad_alloc&)
+            {
+                LL_WARNS("LLVOLUME") << "Resize of mEdge to " << num_indices << " failed" << LL_ENDL;
+                return false;
+            }
 		}
 	}
 
@@ -6782,7 +6799,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
 	LLVector4a* norm = mNormals;
 
 	static LLAlignedArray<LLVector4a, 64> triangle_normals;
-	triangle_normals.resize(count);
+    try
+    {
+        triangle_normals.resize(count);
+    }
+    catch (std::bad_alloc&)
+    {
+        LL_WARNS("LLVOLUME") << "Resize of triangle_normals to " << count << " failed" << LL_ENDL;
+        return false;
+    }
 	LLVector4a* output = triangle_normals.mArray;
 	LLVector4a* end_output = output+count;
 
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 1badd54fca5df6af7b8ab85b69abb5b9b81884ae..33037b500176e2eddb5bdbe8d8bb6439f586085a 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -175,6 +175,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mTripleClickTimer.reset();
 	setText(p.default_text());
 
+    if (p.initial_value.isProvided()
+        && !p.control_name.isProvided())
+    {
+        // Initial value often is descriptive, like "Type some ID here"
+        // and can be longer than size limitation, ignore size
+        setText(p.initial_value.getValue().asString(), false);
+    }
+
 	// Initialize current history line iterator
 	mCurrentHistoryLine = mLineHistory.begin();
 
@@ -389,6 +397,11 @@ void LLLineEditor::updateTextPadding()
 
 
 void LLLineEditor::setText(const LLStringExplicit &new_text)
+{
+    setText(new_text, true);
+}
+
+void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit)
 {
 	// If new text is identical, don't copy and don't move insertion point
 	if (mText.getString() == new_text)
@@ -407,13 +420,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
 	all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived);
 
 	std::string truncated_utf8 = new_text;
-	if (truncated_utf8.size() > (U32)mMaxLengthBytes)
+	if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes)
 	{	
 		truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes);
 	}
 	mText.assign(truncated_utf8);
 
-	if (mMaxLengthChars)
+	if (use_size_limit && mMaxLengthChars)
 	{
 		mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
 	}
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index f84625bea7a680467dbe2cce4e0d2f86499221bf..ae4e05c065f7430e651ab88c60080661c0bfb9bc 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -320,6 +320,8 @@ class LLLineEditor
 	virtual S32		getPreeditFontSize() const;
 	virtual LLWString getPreeditString() const { return getWText(); }
 
+    void			setText(const LLStringExplicit &new_text, bool use_size_limit);
+
 	void			setContextMenu(LLContextMenu* new_context_menu);
 
 protected:
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index cdaf03ebde411a0d48bd896f4368bb36dfa7b65b..76fd789becebe6ff33f41496be5023b58b33c9b5 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -2362,6 +2362,16 @@ void LLMenuGL::arrange( void )
 				(*item_iter)->setRect( rect );
 			}
 		}
+
+
+        if (getTornOff())
+        {
+            LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getParent());
+            if (torn_off_menu)
+            {
+                torn_off_menu->updateSize();
+            }
+        }
 	}
 	if (mKeepFixedSize)
 	{
@@ -3879,7 +3889,8 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item)
 /// Class LLTearOffMenu
 ///============================================================================
 LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : 
-	LLFloater(LLSD())
+	LLFloater(LLSD()),
+    mQuitRequested(false)
 {
 	S32 floater_header_size = getHeaderHeight();
 
@@ -3894,7 +3905,7 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
 	LLRect rect;
 	menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView);
 	// make sure this floater is big enough for menu
-	mTargetHeight = (F32)(rect.getHeight() + floater_header_size);
+	mTargetHeight = rect.getHeight() + floater_header_size;
 	reshape(rect.getWidth(), rect.getHeight());
 	setRect(rect);
 
@@ -3926,19 +3937,24 @@ LLTearOffMenu::~LLTearOffMenu()
 void LLTearOffMenu::draw()
 {
 	mMenu->setBackgroundVisible(isBackgroundOpaque());
-	mMenu->needsArrange();
 
 	if (getRect().getHeight() != mTargetHeight)
 	{
 		// animate towards target height
-		reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
+        reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
+        mMenu->needsArrange();
 	}
 	LLFloater::draw();
 }
 
 void LLTearOffMenu::onFocusReceived()
 {
-	// if nothing is highlighted, just highlight first item
+    if (mQuitRequested)
+    {
+        return;
+    }
+ 
+    // if nothing is highlighted, just highlight first item
 	if (!mMenu->getHighlightedItem())
 	{
 		mMenu->highlightNextItem(NULL);
@@ -4014,6 +4030,31 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup)
 	return tearoffp;
 }
 
+void LLTearOffMenu::updateSize()
+{
+    if (mMenu)
+    {
+        S32 floater_header_size = getHeaderHeight();
+        const LLRect &floater_rect = getRect();
+        LLRect new_rect;
+        mMenu->localRectToOtherView(LLRect(-1, mMenu->getRect().getHeight() + floater_header_size, mMenu->getRect().getWidth() + 3, 0), &new_rect, gFloaterView);
+
+        if (floater_rect.getWidth() != new_rect.getWidth()
+            || mTargetHeight != new_rect.getHeight())
+        {
+            // make sure this floater is big enough for menu
+            mTargetHeight = new_rect.getHeight();
+            reshape(new_rect.getWidth(), mTargetHeight);
+
+            // Restore menu position
+            LLRect menu_rect = mMenu->getRect();
+            menu_rect.setOriginAndSize(1, 1,
+                menu_rect.getWidth(), menu_rect.getHeight());
+            mMenu->setRect(menu_rect);
+        }
+    }
+}
+
 void LLTearOffMenu::closeTearOff()
 {
 	removeChild(mMenu);
@@ -4024,6 +4065,7 @@ void LLTearOffMenu::closeTearOff()
 	mMenu->setVisible(FALSE);
 	mMenu->setTornOff(FALSE);
 	mMenu->setDropShadowed(TRUE);
+    mQuitRequested = true;
 }
 
 LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) 
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 273bd789c44796b1a76740b2a5c6b002ffb7e0b1..abbfd9a24a36c0597045f3f0b12584a68b6931a5 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -873,6 +873,8 @@ class LLTearOffMenu : public LLFloater
 	virtual BOOL handleKeyHere(KEY key, MASK mask);
 	virtual void translate(S32 x, S32 y);
 
+	void updateSize();
+
 private:
 	LLTearOffMenu(LLMenuGL* menup);
 	
@@ -880,7 +882,8 @@ class LLTearOffMenu : public LLFloater
 	
 	LLView*		mOldParent;
 	LLMenuGL*	mMenu;
-	F32			mTargetHeight;
+	S32			mTargetHeight;
+    bool        mQuitRequested;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 38495e1e0b023fbfa5df2c1df942e6c4a0df229d..1547a4ba5c89aa0c0df716e48720989f5e08451f 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -1017,6 +1017,24 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
 	return LLUrlEntryBase::getLocation(url);
 }
 
+//
+// LLUrlEntryChat Describes a Second Life chat Url, e.g.,
+// secondlife:///app/chat/42/This%20Is%20a%20test
+//
+
+LLUrlEntryChat::LLUrlEntryChat()
+{
+    mPattern = boost::regex("secondlife:///app/chat/\\d+/\\S+",
+        boost::regex::perl|boost::regex::icase);
+    mMenuName = "menu_url_slapp.xml";
+    mTooltip = LLTrans::getString("TooltipSLAPP");
+}
+
+std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+    return unescapeUrl(url);
+}
+
 // LLUrlEntryParcel statics.
 LLUUID	LLUrlEntryParcel::sAgentID(LLUUID::null);
 LLUUID	LLUrlEntryParcel::sSessionID(LLUUID::null);
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 102e0a4fd98d7e2537ab2df0cd6f0f427fb49552..63a1506731f73100f97fda9fa27b105e8ebaa175 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -370,6 +370,17 @@ class LLUrlEntryObjectIM : public LLUrlEntryBase
 private:
 };
 
+//
+// LLUrlEntryChat Describes a Second Life chat Url, e.g.,
+// secondlife:///app/chat/42/This%20Is%20a%20test
+//
+class LLUrlEntryChat : public LLUrlEntryBase
+{
+public:
+    LLUrlEntryChat();
+    /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
 ///
 /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
 /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index bfcd970529454c89aa2f09d981f38008144b02b7..c9d7013a11ac5dba1887d0d66cbc9f64c17ca1e4 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -63,6 +63,7 @@ LLUrlRegistry::LLUrlRegistry()
 	// LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since 
 	// LLUrlEntryAgent is a less specific (catchall for agent urls)
 	registerUrl(new LLUrlEntryAgent());
+    registerUrl(new LLUrlEntryChat());
 	registerUrl(new LLUrlEntryGroup());
 	registerUrl(new LLUrlEntryParcel());
 	registerUrl(new LLUrlEntryTeleport());
@@ -71,7 +72,6 @@ LLUrlRegistry::LLUrlRegistry()
 	registerUrl(new LLUrlEntryObjectIM());
 	registerUrl(new LLUrlEntryPlace());
 	registerUrl(new LLUrlEntryInventory());
-	registerUrl(new LLUrlEntryObjectIM());
     registerUrl(new LLUrlEntryExperienceProfile());
 	//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern, 
 	//so it should be registered in the end of list
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index f303d1bb210fda1a31d8639bd785e42e090352c7..a32346bfd32ad76bbc3ebc81b84d97c8926eb235 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -4262,7 +4262,8 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res
 				S32 context_offset;
 				LLWString context = find_context(wtext, preedit, preedit_length, &context_offset);
 				preedit -= context_offset;
-				if (preedit_length)
+				preedit_length = llmin(preedit_length, (S32)context.length() - preedit);
+				if (preedit_length && preedit >= 0)
 				{
 					// IMR_DOCUMENTFEED may be called when we have an active preedit.
 					// We should pass the context string *excluding* the preedit string.
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 43aea7877523c1da52d5a7409cbf432df3ac4e52..6e648485fd869795d402f1102c49c42d64c86411 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1922,9 +1922,7 @@ if (WINDOWS)
       add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
     endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
 
-    add_dependencies(${VIEWER_BINARY_NAME}
-      SLPlugin
-    )
+    add_dependencies(${VIEWER_BINARY_NAME} SLPlugin)
 
     # sets the 'working directory' for debugging from visual studio.
     # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
@@ -2274,7 +2272,7 @@ endif (INSTALL)
 
 # Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
 if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
-  if (BUGSPLAT_DB)
+  if (USE_BUGSPLAT)
     # BugSplat symbol-file generation
     if (WINDOWS)
       # Just pack up a tarball containing only the .pdb file for the
@@ -2358,7 +2356,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
     if (LINUX)
       # TBD
     endif (LINUX)
-  endif (BUGSPLAT_DB)
+  endif (USE_BUGSPLAT)
 
   # for both Bugsplat and Breakpad
   add_dependencies(llpackage generate_symbols)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 54358db763fa41582501e9fc9b6729d54ce7d1e2..cc81d718c3b6f077fd712540699a0dff7c885dba 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.5.4
+6.5.5
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 4e186292f77d6e4c3f99f035e75f3b80141c2179..3100baf9430dbb00b61ddd6f8bc4cdf84de3535c 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -207,14 +207,6 @@
     <map>
       <key>map-to</key>
       <string>NoAudio</string>
-    </map>    
-
-    <key>noinvlib</key>
-    <map>
-      <key>desc</key>
-      <string>Do not request the inventory library.</string>
-      <key>map-to</key>
-      <string>NoInventoryLibrary</string>
     </map>
 
     <key>nonotifications</key>
diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml
index 1a5157838cd7a2f0d5858e5b6ce59af32853091b..55babc88bceaa5acd97ffebcbf00fe598fdeb1f7 100644
--- a/indra/newview/app_settings/key_bindings.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<keys>
+<keys xml_version="1">
   <first_person>
     <binding key="A" mask="NONE" command="slide_left"/>
     <binding key="D" mask="NONE" command="slide_right"/>
@@ -17,22 +17,13 @@
     <binding key="PGDN" mask="NONE" command="push_down"/>
     <binding key="HOME" mask="NONE" command="toggle_fly"/>
 
-    <binding key="PAD_LEFT" mask="NONE" command="slide_left"/>
-    <binding key="PAD_RIGHT" mask="NONE" command="slide_right"/>
-    <binding key="PAD_UP" mask="NONE" command="push_forward"/>
-    <binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
-    <binding key="PAD_PGUP" mask="NONE" command="jump"/>
-    <binding key="PAD_PGDN" mask="NONE" command="push_down"/>
-    <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
-    <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
-    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
-
     <binding key="SPACE" mask="NONE" command="stop_moving"/>
     <binding key="ENTER" mask="NONE" command="start_chat"/>
     <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
 
     <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
+
+    <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
   </first_person>
   <third_person>
     <binding key="A" mask="NONE" command="turn_left"/>
@@ -60,19 +51,6 @@
     <binding key="PGDN" mask="NONE" command="push_down"/>
     <binding key="HOME" mask="NONE" command="toggle_fly"/>
 
-    <binding key="PAD_LEFT" mask="NONE" command="turn_left"/>
-    <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
-    <binding key="PAD_RIGHT" mask="NONE" command="turn_right"/>
-    <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
-    <binding key="PAD_UP" mask="NONE" command="push_forward"/>
-    <binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
-    <binding key="PAD_PGUP" mask="NONE" command="jump"/>
-    <binding key="PAD_PGDN" mask="NONE" command="push_down"/>
-    <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
-    <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
-    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
-
     <!--Camera controls in third person on Alt-->
     <binding key="LEFT" mask="ALT" command="spin_around_cw"/>
     <binding key="RIGHT" mask="ALT" command="spin_around_ccw"/>
@@ -88,15 +66,6 @@
     <binding key="E" mask="ALT" command="spin_over"/>
     <binding key="C" mask="ALT" command="spin_under"/>
 
-    <binding key="PAD_LEFT" mask="ALT" command="spin_around_cw"/>
-    <binding key="PAD_RIGHT" mask="ALT" command="spin_around_ccw"/>
-    <binding key="PAD_UP" mask="ALT" command="move_forward"/>
-    <binding key="PAD_DOWN" mask="ALT" command="move_backward"/>
-    <binding key="PAD_PGUP" mask="ALT" command="spin_over"/>
-    <binding key="PAD_PGDN" mask="ALT" command="spin_under"/>
-    <binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
-
     <!--mimic alt zoom behavior with keyboard only-->
     <binding key="W" mask="CTL_ALT" command="spin_over"/>
     <binding key="S" mask="CTL_ALT" command="spin_under"/>
@@ -104,9 +73,6 @@
     <binding key="UP" mask="CTL_ALT" command="spin_over"/>
     <binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
 
-    <binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/>
-    <binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/>
-
     <!--Therefore pan on Alt-Shift-->
     <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
     <binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
@@ -118,14 +84,10 @@
     <binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
     <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
 
-    <binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
-    <binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
-    <binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
-    <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
-    <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
-
     <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
+    <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
+
+    <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
   </third_person>
   <sitting>
     <binding key="A" mask="ALT" command="spin_around_cw"/>
@@ -167,16 +129,6 @@
     <binding key="PGUP" mask="NONE" command="spin_over_sitting"/>
     <binding key="PGDN" mask="NONE" command="spin_under_sitting"/>
 
-    <binding key="PAD_LEFT" mask="NONE" command="spin_around_cw_sitting"/>
-    <binding key="PAD_RIGHT" mask="NONE" command="spin_around_ccw_sitting"/>
-    <binding key="PAD_UP" mask="NONE" command="move_forward_sitting"/>
-    <binding key="PAD_DOWN" mask="NONE" command="move_backward_sitting"/>
-    <binding key="PAD_PGUP" mask="NONE" command="spin_over_sitting"/>
-    <binding key="PAD_PGDN" mask="NONE" command="spin_under_sitting"/>
-    <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
-    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
-
     <!--these are for passing controls when sitting on vehicles-->
     <binding key="A" mask="SHIFT" command="slide_left"/>
     <binding key="D" mask="SHIFT" command="slide_right"/>
@@ -192,15 +144,6 @@
     <binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
     <binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
 
-    <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
-    <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
-    <binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/>
-    <binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
-    <binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
-    <binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/> 
-    <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
-
     <!--pan on Alt-Shift-->
     <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
     <binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
@@ -212,17 +155,12 @@
     <binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
     <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
 
-    <binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
-    <binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
-    <binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
-    <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
-    <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
-
     <binding key="ENTER" mask="NONE" command="start_chat"/>
     <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
 
     <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
+
+    <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
   </sitting>
   <edit_avatar>
     <!--Avatar editing camera controls-->
@@ -240,15 +178,9 @@
     <binding key="PGDN" mask="NONE" command="edit_avatar_spin_under"/>
     <binding key="ENTER" mask="NONE" command="start_chat"/>
     <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
-    <binding key="PAD_LEFT" mask="NONE" command="edit_avatar_spin_cw"/>
-    <binding key="PAD_RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/>
-    <binding key="PAD_UP" mask="NONE" command="edit_avatar_move_forward"/>
-    <binding key="PAD_DOWN" mask="NONE" command="edit_avatar_move_backward"/>
-    <binding key="PAD_PGUP" mask="NONE" command="edit_avatar_spin_over"/>
-    <binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/>
-    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
 
     <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
+
+    <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
   </edit_avatar>
 </keys>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7d39a54c1dc4b2e157782e2d46b296cff602d8f0..c13329dc4a0a2d08e035b4d901cc19bb1273bde4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4758,7 +4758,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
+      <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
     </map>
     <key>GuidebookURL</key>
     <map>
@@ -5895,17 +5895,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>LoginAsGod</key>
-    <map>
-      <key>Comment</key>
-      <string>Attempt to login with god powers (Linden accounts only)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>LoginLocation</key>
     <map>
       <key>Comment</key>
@@ -6964,6 +6953,17 @@
       <key>Value</key>
       <integer>1000</integer>
     </map>
+	<key>FakeInitialOutfitName</key>
+	<map>
+		<key>Comment</key>
+		<string>Pretend that this is first time login and specified name was chosen</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+        <string>String</string>
+        <key>Value</key>
+        <string />
+	</map>
 	<key>MyOutfitsAutofill</key>
 	<map>
 		<key>Comment</key>
@@ -7066,7 +7066,7 @@
     <key>NoInventoryLibrary</key>
     <map>
       <key>Comment</key>
-      <string>Do not request inventory library.</string>
+      <string>(Deprecated) Do not request inventory library.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9cae1dd930f5cf4c765c0778833857fb33eec6f2..d5d0d044c0ebf6242296a5602ac18588f610aed4 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1988,7 +1988,8 @@ void LLAgent::propagate(const F32 dt)
 //-----------------------------------------------------------------------------
 void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
 {
-	if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout"))
+    static LLCachedControl<F32> hint_timeout(gSavedSettings, "NotMovingHintTimeout");
+	if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > hint_timeout)
 	{
 		LLFirstUse::notMoving();
 	}
@@ -2159,7 +2160,8 @@ void LLAgent::endAnimationUpdateUI()
 		LLNavigationBar::getInstance()->setVisible(TRUE && gSavedSettings.getBOOL("ShowNavbarNavigationPanel"));
 		gStatusBar->setVisibleForMouselook(true);
 
-		if (gSavedSettings.getBOOL("ShowMiniLocationPanel"))
+        static LLCachedControl<bool> show_mini_location_panel(gSavedSettings, "ShowMiniLocationPanel");
+		if (show_mini_location_panel)
 		{
 			LLPanelTopInfoBar::getInstance()->setVisible(TRUE);
 		}
@@ -3901,10 +3903,6 @@ bool LLAgent::teleportCore(bool is_local)
 	// yet if the teleport will succeed.  Look in 
 	// process_teleport_location_reply
 
-	// close the map panel so we can see our destination.
-	// we don't close search floater, see EXT-5840.
-	LLFloaterReg::hideInstance("world_map");
-
 	// hide land floater too - it'll be out of date
 	LLFloaterReg::hideInstance("about_land");
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d46dc2ff35b829d8a54468a811f7be8ff2421181..38bf2bdf9facc9d5ae36ed49281fceb5fd896e37 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5324,14 +5324,18 @@ void LLAppViewer::disconnectViewer()
 	}
 
 	// save inventory if appropriate
-	gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
-	if (gInventory.getLibraryRootFolderID().notNull()
-		&& gInventory.getLibraryOwnerID().notNull())
-	{
-		gInventory.cache(
-			gInventory.getLibraryRootFolderID(),
-			gInventory.getLibraryOwnerID());
-	}
+    if (gInventory.isInventoryUsable()
+        && gAgent.getID().notNull()) // Shouldn't be null at this stage
+    {
+        gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
+        if (gInventory.getLibraryRootFolderID().notNull()
+            && gInventory.getLibraryOwnerID().notNull())
+        {
+            gInventory.cache(
+                gInventory.getLibraryRootFolderID(),
+                gInventory.getLibraryOwnerID());
+        }
+    }
 
 	saveNameCache();
 	if (LLExperienceCache::instanceExists())
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index 82b6b0c77c8089fa8ad911a481984f8b1df43273..ab52bf15f9e7d7fa51643dff8e526244c68b4fe4 100644
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -51,8 +51,8 @@ class LLAppViewerWin32 : public LLAppViewer
 	bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
 	bool initParseCommandLine(LLCommandLineParser& clp) override;
 
-	virtual bool beingDebugged();
-	virtual bool restoreErrorTrap();
+	bool beingDebugged() override;
+	bool restoreErrorTrap() override;
 
 	bool sendURLToOtherInstance(const std::string& url) override;
 
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index ca83afb5ab070e69d40ae80bc457fdb4e911a4b6..04dbf03e31aeef34df824b99a5cca3bc8d9bc6f3 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -345,6 +345,8 @@ void LLAvatarRenderInfoAccountant::idle()
 				&& regionp->capabilitiesReceived())
 			{
 				// each of these is further governed by and resets its own timer
+                // Note: We can have multiple regions, each launches up to two coroutines,
+                // it likely is expensive
 				sendRenderInfoToRegion(regionp);
 				getRenderInfoFromRegion(regionp);
 			}
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 6d20b23e9f9b4a733ee936d60561c54f2fa5ac42..43e39d307322c4f7ac4a2b3502349da7f2d41b8c 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -645,7 +645,8 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
 		{
 			if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
 			{
-				if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^  new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
+                if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^  new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
+                    && !gAgent.isDoNotDisturb())
 				{
 					LLSD args;
 					args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString();
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index fee85d50bd4305521109f995fcb8088ba1147687..20fa6d490b4562c24c3bf13349103130b07d61af 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -96,10 +96,14 @@ LLConversationViewSession::~LLConversationViewSession()
 {
 	mActiveVoiceChannelConnection.disconnect();
 
-	if(LLVoiceClient::instanceExists() && mVoiceClientObserver)
-	{
-		LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
-	}
+    if (mVoiceClientObserver)
+    {
+        if (LLVoiceClient::instanceExists())
+        {
+            LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+        }
+        delete mVoiceClientObserver;
+    }
 
 	mFlashTimer->unset();
 }
@@ -255,7 +259,12 @@ BOOL LLConversationViewSession::postBuild()
 			mIsInActiveVoiceChannel = true;
 			if(LLVoiceClient::instanceExists())
 			{
-				LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
+                if (mVoiceClientObserver)
+                {
+                    LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+                    delete mVoiceClientObserver;
+                }
+				mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
 				LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
 			}
 			break;
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 4ee08e869a087c650b66dff9dd3de387e0eba16a..91b0e40aa9b32b8f44b08261949b1aaf161ea73d 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -615,12 +615,12 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
 
 void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 {
-    BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights");
-    BOOL batch_emissives   = gSavedSettings.getBOOL("RenderAlphaBatchEmissives");
-	BOOL initialized_lighting = FALSE;
-	BOOL light_enabled = TRUE;
+    static LLCachedControl<bool> batch_fullbrights(gSavedSettings, "RenderAlphaBatchFullbrights");
+    static LLCachedControl<bool> batch_emissives(gSavedSettings, "RenderAlphaBatchEmissives");
+	bool initialized_lighting = FALSE;
+	bool light_enabled = TRUE;
 	
-	BOOL use_shaders = gPipeline.canUseVertexShaders();
+	bool use_shaders = gPipeline.canUseVertexShaders();
 		
 	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
 	{
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index aa426cd785667714b3d2928a06bb0ea1ab658f88..3d1a292ba235980ca1b522d4ff7f7d006896ad82 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -574,18 +574,8 @@ void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& li
 	shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
 	shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
 	shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
-    if (LLEnvironment::instance().isCloudScrollPaused())
-    {
-        static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} };
-        
-        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
-        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
-    }
-    else
-    {
-        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
-        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
-    }
+    shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+    shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
 	shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
 
 	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 3b192ff81b00c0ba6cdb1742ed94f78f570b4050..1c69b9d60baa026ba66c90e94c5b325658cc75b8 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -453,18 +453,18 @@ void LLFloaterCamera::setMode(ECameraControlMode mode)
 
 void LLFloaterCamera::switchMode(ECameraControlMode mode)
 {
-	setMode(mode);
-
 	switch (mode)
 	{
 	case CAMERA_CTRL_MODE_PRESETS:
 	case CAMERA_CTRL_MODE_PAN:
 		sFreeCamera = false;
+		setMode(mode); // depends onto sFreeCamera
 		clear_camera_tool();
 		break;
 
 	case CAMERA_CTRL_MODE_FREE_CAMERA:
 		sFreeCamera = true;
+		setMode(mode);
 		activate_camera_tool();
 		break;
 
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index c4e0dd483fa04521c72899959804f4f42927517c..6e326ff3cf041cc0c11ce86a23010f2eac9d509e 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -582,8 +582,7 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
 			LLInventoryItem* item = gInventory.getItem(*it);
 			if(item  && item->getInventoryType() == LLInventoryType::IT_GESTURE)
 			{
-				LLWString item_name = utf8str_to_wstring(item->getName());
-				LLClipboard::instance().addToClipboard(item_name, 0, item_name.size());
+				LLClipboard::instance().addToClipboard(*it);
 			}
 		}
 	}
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 43dc304c1076039d180468a37dbd0d6dbab15372..34499ac170e1ecf02a81ac952c33b009ecc7ddea 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -384,7 +384,7 @@ void LLFloaterIMSessionTab::draw()
 
 void LLFloaterIMSessionTab::enableDisableCallBtn()
 {
-    if (LLVoiceClient::instanceExists())
+    if (LLVoiceClient::instanceExists() && mVoiceButton)
     {
         mVoiceButton->setEnabled(
             mSessionID.notNull()
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 1fc734ae39ca643c6571f14dbbb417b649910796..9064a65d0585a6fd5d1567a7e4255ca81e22d58a 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2399,7 +2399,16 @@ void LLPanelPreference::saveSettings()
 		{
 			view_stack.push_back(*iter);
 		}
-	}	
+	}
+
+    if (LLStartUp::getStartupState() == STATE_STARTED)
+    {
+        LLControlVariable* control = gSavedPerAccountSettings.getControl("VoiceCallsFriendsOnly");
+        if (control)
+        {
+            mSavedValues[control] = control->getValue();
+        }
+    }
 }
 
 void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value)
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 779542cfcc8821d83232b693f5f02ae7663f1b72..2e1fbb09e0e398a3bac23a5875b3c3d52fb54528 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -169,15 +169,6 @@ void LLFloaterSearch::search(const SearchQuery &p)
 	// add the search query string
 	subs["QUERY"] = LLURI::escape(p.query);
 
-	// add the permissions token that login.cgi gave us
-	// We use "search_token", and fallback to "auth_token" if not present.
-	LLSD search_token = LLLoginInstance::getInstance()->getResponse("search_token");
-	if (search_token.asString().empty())
-	{
-		search_token = LLLoginInstance::getInstance()->getResponse("auth_token");
-	}
-	subs["AUTH_TOKEN"] = search_token.asString();
-
 	// add the user's preferred maturity (can be changed via prefs)
 	std::string maturity;
 	if (gAgent.prefersAdult())
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 27197f0b065075055cef8c772c0a6f82247027a1..2c84cd1f93ddd84eb092d8655e5ceef70f8bd275 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -56,10 +56,12 @@
 #include "llscrolllistctrl.h"
 #include "llslurl.h"
 #include "lltextbox.h"
+#include "lltoolbarview.h"
 #include "lltracker.h"
 #include "lltrans.h"
 #include "llviewerinventory.h"	// LLViewerInventoryItem
 #include "llviewermenu.h"
+#include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "llviewertexture.h"
@@ -87,6 +89,9 @@ static const F32 MAP_ZOOM_TIME = 0.2f;
 // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
 static const S32 MAX_VISIBLE_REGIONS = 512;
 
+
+const S32 HIDE_BEACON_PAD = 133;
+
 // It would be more logical to have this inside the method where it is used but to compile under gcc this
 // struct has to be here.
 struct SortRegionNames
@@ -326,6 +331,8 @@ LLFloaterWorldMap::~LLFloaterWorldMap()
 	mFriendObserver = NULL;
 	
 	gFloaterWorldMap = NULL;
+
+    mTeleportFinishConnection.disconnect();
 }
 
 //static
@@ -339,12 +346,16 @@ void LLFloaterWorldMap::onClose(bool app_quitting)
 {
 	// While we're not visible, discard the overlay images we're using
 	LLWorldMap::getInstance()->clearImageRefs();
+    mTeleportFinishConnection.disconnect();
 }
 
 // virtual
 void LLFloaterWorldMap::onOpen(const LLSD& key)
 {
-	bool center_on_target = (key.asString() == "center");
+    mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
+        setTeleportFinishedCallback(boost::bind(&LLFloaterWorldMap::onTeleportFinished, this));
+ 
+    bool center_on_target = (key.asString() == "center");
 	
 	mIsClosing = FALSE;
 	
@@ -1566,6 +1577,13 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim)
 	}
 }
 
+void LLFloaterWorldMap::onTeleportFinished()
+{
+    if(isInVisibleChain())
+    {
+        LLWorldMapView::setPan(0, 0, TRUE);
+    }
+}
 
 void LLFloaterWorldMap::onCommitSearchResult()
 {
@@ -1642,3 +1660,103 @@ void LLFloaterWorldMap::onFocusLost()
 	LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
 	map_panel->mPanning = FALSE;
 }
+
+LLPanelHideBeacon::LLPanelHideBeacon() :
+	mHideButton(NULL)
+{
+}
+
+// static
+LLPanelHideBeacon* LLPanelHideBeacon::getInstance()
+{
+	static LLPanelHideBeacon* panel = getPanelHideBeacon();
+	return panel;
+}
+
+
+BOOL LLPanelHideBeacon::postBuild()
+{
+	mHideButton = getChild<LLButton>("hide_beacon_btn");
+	mHideButton->setCommitCallback(boost::bind(&LLPanelHideBeacon::onHideButtonClick, this));
+
+	gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelHideBeacon::updatePosition, this));
+
+	return TRUE;
+}
+
+//virtual
+void LLPanelHideBeacon::draw()
+{
+	if (!LLTracker::isTracking(NULL))
+	{
+        mHideButton->setVisible(false);
+        return;
+	}
+    mHideButton->setVisible(true);
+	updatePosition(); 
+	LLPanel::draw();
+}
+
+//virtual
+void LLPanelHideBeacon::setVisible(BOOL visible)
+{
+	if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false;
+
+	if (visible)
+	{
+		updatePosition();
+	}
+
+	LLPanel::setVisible(visible);
+}
+
+
+//static
+LLPanelHideBeacon* LLPanelHideBeacon::getPanelHideBeacon()
+{
+	LLPanelHideBeacon* panel = new LLPanelHideBeacon();
+	panel->buildFromFile("panel_hide_beacon.xml");
+
+	LL_INFOS() << "Build LLPanelHideBeacon panel" << LL_ENDL;
+
+	panel->updatePosition();
+	return panel;
+}
+
+void LLPanelHideBeacon::onHideButtonClick()
+{
+	LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
+	if (instance)
+	{
+		instance->onClearBtn();
+	}
+}
+
+/**
+* Updates position of the panel (similar to Stand & Stop Flying panel).
+*/
+void LLPanelHideBeacon::updatePosition()
+{
+	S32 bottom_tb_center = 0;
+	if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM))
+	{
+		bottom_tb_center = toolbar_bottom->getRect().getCenterX();
+	}
+
+	S32 left_tb_width = 0;
+	if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT))
+	{
+		left_tb_width = toolbar_left->getRect().getWidth();
+	}
+
+	if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons())
+	{
+		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width;
+		setOrigin( x_pos + HIDE_BEACON_PAD, 0);
+	}
+	else 
+	{
+		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2;
+		setOrigin( x_pos + HIDE_BEACON_PAD, 0);
+	}
+}
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 97e99297cfe60e11ee9f5b51d0c61c7075e18369..14a9c26fb97fe7687eb540e06c154ade3fb26621 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -107,7 +107,8 @@ class LLFloaterWorldMap : public LLFloater
 	// teleport to the tracked item, if there is one
 	void			teleport();
 	void			onChangeMaturity();
-	
+
+	void			onClearBtn();
 	
 	//Slapp instigated avatar tracking
 	void			avatarTrackFromSlapp( const LLUUID& id ); 
@@ -124,7 +125,6 @@ class LLFloaterWorldMap : public LLFloater
 	void			onComboTextEntry( );
 	void			onSearchTextEntry( );
 
-	void			onClearBtn();
 	void			onClickTeleportBtn();
 	void			onShowTargetBtn();
 	void			onShowAgentBtn();
@@ -151,7 +151,7 @@ class LLFloaterWorldMap : public LLFloater
 	void			onCoordinatesCommit();
 	void		    onCommitSearchResult();
 
-	void			cacheLandmarkPosition();
+    void            onTeleportFinished();
 
 private:
 	LLPanel*			mPanel;		// Panel displaying the map
@@ -195,9 +195,31 @@ class LLFloaterWorldMap : public LLFloater
 	LLCtrlListInterface *	mListFriendCombo;
 	LLCtrlListInterface *	mListLandmarkCombo;
 	LLCtrlListInterface *	mListSearchResults;
+
+    boost::signals2::connection mTeleportFinishConnection;
 };
 
 extern LLFloaterWorldMap* gFloaterWorldMap;
 
+
+class LLPanelHideBeacon : public LLPanel
+{
+public:
+	static LLPanelHideBeacon* getInstance();
+
+	LLPanelHideBeacon();
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void draw();
+
+private:
+	static LLPanelHideBeacon* getPanelHideBeacon();
+	void onHideButtonClick();
+	void updatePosition();
+
+	LLButton* mHideButton;
+
+};
+
 #endif
 
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 9f2119281d367d418d2b68f47479da252c3c6d22..489d34edca403173a755b0e3479a911c678f6223 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -483,8 +483,13 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, LLMultiGesture* new_ges
 
 	mActive[base_item_id] = new_gesture;
 
-	delete old_gesture;
-	old_gesture = NULL;
+    // replaceGesture(const LLUUID& item_id, const LLUUID& new_asset_id)
+    // replaces ids without repalcing gesture
+    if (old_gesture != new_gesture)
+    {
+        delete old_gesture;
+        old_gesture = NULL;
+    }
 
 	if (asset_id.notNull())
 	{
@@ -910,7 +915,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
 			else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_ANIM_SECS)
 			{
 				// we've waited too long for an animation
-				LL_INFOS() << "Waited too long for animations to stop, continuing gesture."
+				LL_INFOS("GestureMgr") << "Waited too long for animations to stop, continuing gesture."
 					<< LL_ENDL;
 				gesture->mWaitingAnimations = FALSE;
 				gesture->mCurrentStep++;
@@ -1097,6 +1102,34 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid,
 				self.setFetchID(item_id);
 				self.startFetch();
 			}
+
+            item_map_t::iterator it = self.mActive.find(item_id);
+            if (it == self.mActive.end())
+            {
+                // Gesture is supposed to be present, active, but NULL
+                LL_DEBUGS("GestureMgr") << "Gesture " << item_id << " not found in active list" << LL_ENDL;
+            }
+            else
+            {
+                LLMultiGesture* old_gesture = (*it).second;
+                if (old_gesture && old_gesture != gesture)
+                {
+                    LL_DEBUGS("GestureMgr") << "Received dupplicate " << item_id << " callback" << LL_ENDL;
+                    // In case somebody managest to activate, deactivate and
+                    // then activate gesture again, before asset finishes loading.
+                    // LLLoadInfo will have a different pointer, asset storage will
+                    // see it as a different request, resulting in two callbacks.
+
+                    // deactivateSimilarGestures() did not turn this one off
+                    // because of matching item_id
+                    self.stopGesture(old_gesture);
+
+                    self.mActive.erase(item_id);
+                    delete old_gesture;
+                    old_gesture = NULL;
+                }
+            }
+
 			self.mActive[item_id] = gesture;
 
 			// Everything has been successful.  Add to the active list.
@@ -1131,9 +1164,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid,
 		}
 		else
 		{
-			LL_WARNS() << "Unable to load gesture" << LL_ENDL;
-
-			self.mActive.erase(item_id);
+			LL_WARNS("GestureMgr") << "Unable to load gesture" << LL_ENDL;
+
+            item_map_t::iterator it = self.mActive.find(item_id);
+            if (it != self.mActive.end())
+            {
+                LLMultiGesture* old_gesture = (*it).second;
+                if (old_gesture)
+                {
+                    // Shouldn't happen, just in case
+                    LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL;
+
+                    self.stopGesture(old_gesture);
+                    delete old_gesture;
+                    old_gesture = NULL;
+                }
+                self.mActive.erase(item_id);
+            }
 			
 			delete gesture;
 			gesture = NULL;
@@ -1151,9 +1198,23 @@ void LLGestureMgr::onLoadComplete(const LLUUID& asset_uuid,
 			LLDelayedGestureError::gestureFailedToLoad( item_id );
 		}
 
-		LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL;
-		
-		LLGestureMgr::instance().mActive.erase(item_id);			
+		LL_WARNS("GestureMgr") << "Problem loading gesture: " << status << LL_ENDL;
+        
+        item_map_t::iterator it = self.mActive.find(item_id);
+        if (it != self.mActive.end())
+        {
+            LLMultiGesture* old_gesture = (*it).second;
+            if (old_gesture)
+            {
+                // Shouldn't happen, just in case
+                LL_WARNS("GestureMgr") << "Gesture " << item_id << " existed when it shouldn't" << LL_ENDL;
+
+                self.stopGesture(old_gesture);
+                delete old_gesture;
+                old_gesture = NULL;
+            }
+            self.mActive.erase(item_id);
+        }
 	}
 }
 
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 9dca50926299a0a9e04ac27b0af1de9f0510759d..e7bc2a926852104ce4d70d75f4ca22a750669098 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
 // static
 void LLGroupActions::search()
 {
-	LLFloaterReg::showInstance("search", LLSD().with("category", "groups"));
+	LLFloaterReg::showInstance("search");
 }
 
 // static
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b4fc83259659ae69cce18a63db83552e4dc5c190..37500176ea5f5b280c9aa4e02215ca8fef2fb1e6 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -138,6 +138,8 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
 LLInventoryValidationInfo::LLInventoryValidationInfo():
 	mFatalErrorCount(0),
 	mWarningCount(0),
+    mLoopCount(0),
+    mOrphanedCount(0),
 	mInitialized(false),
 	mFatalNoRootFolder(false),
 	mFatalNoLibraryRootFolder(false),
@@ -147,7 +149,10 @@ LLInventoryValidationInfo::LLInventoryValidationInfo():
 
 void LLInventoryValidationInfo::toOstream(std::ostream& os) const
 {
-	os << "mFatalErrorCount " << mFatalErrorCount << " mWarningCount " << mWarningCount;
+	os << "mFatalErrorCount " << mFatalErrorCount
+       << " mWarningCount " << mWarningCount
+       << " mLoopCount " << mLoopCount
+       << " mOrphanedCount " << mOrphanedCount;
 }
 
 
@@ -161,6 +166,8 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
 {
 	sd["fatal_error_count"] = mFatalErrorCount;
 	sd["warning_count"] = mWarningCount;
+    sd["loop_count"] = mLoopCount;
+    sd["orphaned_count"] = mOrphanedCount;
 	sd["initialized"] = mInitialized;
 	sd["missing_system_folders_count"] = LLSD::Integer(mMissingRequiredSystemFolders.size());
 	sd["fatal_no_root_folder"] = mFatalNoRootFolder;
@@ -337,21 +344,35 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
 	return NULL;
 }
 
-bool LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
+LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
 {
 	LLInventoryObject *object = getObject(object_id);
-	while (object && object->getParentUUID().notNull())
-	{
-		LLInventoryObject *parent_object = getObject(object->getParentUUID());
+    if (!object)
+    {
+        LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
+        return ANSCESTOR_MISSING;
+    }
+
+    std::set<LLUUID> object_ids{ object_id }; // loop protection
+    while (object->getParentUUID().notNull())
+    {
+        LLUUID parent_id = object->getParentUUID();
+        if (object_ids.find(parent_id) != object_ids.end())
+        {
+            LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
+            return ANSCESTOR_LOOP;
+        }
+        object_ids.insert(parent_id);
+        LLInventoryObject *parent_object = getObject(parent_id);
 		if (!parent_object)
 		{
-			LL_WARNS(LOG_INV) << "unable to trace topmost ancestor, missing item for uuid " << object->getParentUUID() << LL_ENDL;
-			return false;
+			LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
+			return ANSCESTOR_MISSING;
 		}
 		object = parent_object;
 	}
 	result = object->getUUID();
-	return true;
+	return ANSCESTOR_OK;
 }
 
 // Get the object by id. Returns NULL if not found.
@@ -2947,42 +2968,69 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
 
 	LL_INFOS(LOG_INV) << "saving inventory to: (" << filename << ")" << LL_ENDL;
 
-	llofstream fileXML(filename.c_str());
-	if (!fileXML.is_open())
-	{
-		LL_WARNS(LOG_INV) << "unable to save inventory to: " << filename << LL_ENDL;
-		return false;
-	}
+    try
+    {
+        llofstream fileXML(filename.c_str());
+        if (!fileXML.is_open())
+        {
+            LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL;
+            return false;
+        }
 
-	LLSD cache_ver;
-	cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
+        LLSD cache_ver;
+        cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
 
-	fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
+        if (fileXML.fail())
+        {
+            LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL;
+            return false;
+        }
 
-	S32 count = categories.size();
-	S32 cat_count = 0;
-	S32 i;
-	for(i = 0; i < count; ++i)
-	{
-		LLViewerInventoryCategory* cat = categories[i];
-		if(cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
-		{
-			fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
-			cat_count++;
-		}
-	}
+        fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
 
-	S32 it_count = items.size();
-	for(i = 0; i < it_count; ++i)
-	{
-		fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
-	}
+        S32 count = categories.size();
+        S32 cat_count = 0;
+        S32 i;
+        for (i = 0; i < count; ++i)
+        {
+            LLViewerInventoryCategory* cat = categories[i];
+            if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
+            {
+                fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl;
+                cat_count++;
+            }
 
-	fileXML.close();
+            if (fileXML.fail())
+            {
+                LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL;
+                return false;
+            }
+        }
 
-	LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
+        S32 it_count = items.size();
+        for (i = 0; i < it_count; ++i)
+        {
+            fileXML << LLSDOStreamer<LLSDNotationFormatter>(items[i]->asLLSD()) << std::endl;
 
-	return true;
+            if (fileXML.fail())
+            {
+                LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL;
+                return false;
+            }
+        }
+
+        fileXML.close();
+
+        LL_INFOS(LOG_INV) << "Inventory saved: " << cat_count << " categories, " << it_count << " items." << LL_ENDL;
+    }
+    catch (...)
+    {
+        LOG_UNHANDLED_EXCEPTION("");
+        LL_INFOS(LOG_INV) << "Failed to save inventory to: (" << filename << ")" << LL_ENDL;
+        return false;
+    }
+
+    return true;
 }
 
 // message handling functionality
@@ -3850,20 +3898,23 @@ void LLInventoryModel::dumpInventory() const
 LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 {
 	LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
-	S32 fatalities = 0;
+	S32 fatal_errs = 0;
 	S32 warnings = 0;
+    S32 loops = 0;
+    S32 orphaned = 0;
 
 	if (getRootFolderID().isNull())
 	{
 		LL_WARNS("Inventory") << "Fatal inventory corruption: no root folder id" << LL_ENDL;
 		validation_info->mFatalNoRootFolder = true;
-		fatalities++;
+        fatal_errs++;
 	}
 	if (getLibraryRootFolderID().isNull())
 	{
+        // Probably shouldn't be a fatality, inventory can function without a library 
 		LL_WARNS("Inventory") << "Fatal inventory corruption: no library root folder id" << LL_ENDL;
 		validation_info->mFatalNoLibraryRootFolder = true;
-		fatalities++;
+        fatal_errs++;
 	}
 
 	if (mCategoryMap.size() + 1 != mParentChildCategoryTree.size())
@@ -3895,7 +3946,23 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 		}
 		LLUUID topmost_ancestor_id;
 		// Will leave as null uuid on failure
-		getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
+        EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
+        switch (res)
+        {
+        case ANSCESTOR_MISSING:
+            orphaned++;
+            break;
+        case ANSCESTOR_LOOP:
+            loops++;
+            break;
+        case ANSCESTOR_OK:
+            break;
+        default:
+            LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
+            warnings++;
+            break;
+        }
+
 		if (cat_id != cat->getUUID())
 		{
 			LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
@@ -3995,8 +4062,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 
 			// Topmost ancestor should be root or library.
 			LLUUID topmost_ancestor_id;
-			bool found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
-			if (!found)
+            EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
+			if (found != ANSCESTOR_OK)
 			{
 				LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
 				warnings++;
@@ -4026,7 +4093,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 			{
 				LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
 									  << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
-				warnings++;
+                orphaned++;
 			}
 			else
 			{
@@ -4044,6 +4111,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 				{
 					LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
 										  << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
+                    orphaned++;
 				}
 			}
 		}
@@ -4052,7 +4120,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 		LLFolderType::EType folder_type = cat->getPreferredType();
 		bool cat_is_in_library = false;
 		LLUUID topmost_id;
-		if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) && topmost_id == getLibraryRootFolderID())
+		if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
 		{
 			cat_is_in_library = true;
 		}
@@ -4092,6 +4160,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 		if (parent_id.isNull())
 		{
 			LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
+            orphaned++;
 		}
 		else
 		{
@@ -4102,6 +4171,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 			{
 				LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
 									  << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
+                orphaned++;
 			}
 			else
 			{
@@ -4118,6 +4188,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 				{
 					LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
 										  << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
+                    orphaned++;
 				}
 			}
 				
@@ -4135,15 +4206,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 				LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
 									  << " missing backlink info at target_id " << target_id
 									  << LL_ENDL;
+                orphaned++;
 			}
 			// Links should have referents.
 			if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
 			{
 				LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
+                orphaned++;
 			}
 			else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
 			{
 				LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
+                orphaned++;
 			}
 			if (target_item && target_item->getIsLinkType())
 			{
@@ -4215,8 +4289,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 				if (is_automatic)
 				{
 					LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
-					fatalities++;
-					validation_info->mMissingRequiredSystemFolders.insert(LLFolderType::EType(ft));
+                    fatal_errs++;
+					validation_info->mMissingRequiredSystemFolders.insert(folder_type);
 				}
 				else
 				{
@@ -4227,8 +4301,20 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 			else if (count_under_root > 1)
 			{
 				LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL;
-				validation_info->mDuplicateRequiredSystemFolders.insert(LLFolderType::EType(ft));
-				fatalities++;
+				validation_info->mDuplicateRequiredSystemFolders.insert(folder_type);
+                if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS)
+                {
+                    // It is a fatal problem or can lead to fatal problems for COF,
+                    // outfits, trash and other non-automatic folders.
+                    fatal_errs++;
+                }
+                else
+                {
+                    // For automatic folders it's not a fatal issue and shouldn't
+                    // break inventory or other functionality further
+                    // Exception: FT_SETTINGS is not automatic, but only deserves a warning.
+                    warnings++;
+                }
 			}
 			if (count_elsewhere > 0)
 			{
@@ -4254,11 +4340,13 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
 	}
 
 	// FIXME need to fail login and tell user to retry, contact support if problem persists.
-	bool valid = (fatalities == 0);
-	LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatalities << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
+	bool valid = (fatal_errs == 0);
+	LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
 
-	validation_info->mFatalErrorCount = fatalities;
+	validation_info->mFatalErrorCount = fatal_errs;
 	validation_info->mWarningCount = warnings;
+    validation_info->mLoopCount = loops;
+    validation_info->mOrphanedCount = orphaned;
 
 	return validation_info; 
 }
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index e81652820f5bc54fdcab0acc1b21a4fb0f796737..eeec89bfb0332197da234f1e1985b671d9cce1f1 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -68,6 +68,8 @@ class LLInventoryValidationInfo: public LLRefCount
 
 	S32 mFatalErrorCount;
 	S32 mWarningCount;
+    S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
+    S32 mOrphanedCount; // Missing or orphaned items, links and folders
 	bool mInitialized;
 	bool mFatalNoRootFolder;
 	bool mFatalNoLibraryRootFolder;
@@ -283,9 +285,14 @@ class LLInventoryModel
 
 	// Check if one object has a parent chain up to the category specified by UUID.
 	BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
-
+    
+    enum EAnscestorResult{
+        ANSCESTOR_OK = 0,
+        ANSCESTOR_MISSING = 1,
+        ANSCESTOR_LOOP = 2,
+    };
 	// Follow parent chain to the top.
-	bool getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
+    EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
 
 	//--------------------------------------------------------------------
 	// Find
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index b5ac94b1cd5d43d9744d8f52b1547c6f0aaf5976..d3ba18525be1803413e773660660a2ffc2547d09 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -411,8 +411,16 @@ void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
         filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
         if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap))
         {
-            // mind placeholders
-            mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+            // Mind placeholders
+            // Do not use mControlsMap.insert(mDefaultsMap) since mControlsMap has
+            // placeholders that won't be added over(to) by insert.
+            // Or instead move generatePlaceholders call to be after copying
+            control_map_t::iterator iter = mDefaultsMap.begin();
+            while (iter != mDefaultsMap.end())
+            {
+                mControlsMap[iter->first].mKeyBind = iter->second.mKeyBind;
+                iter++;
+            }
         }
     }
     mLoadMode = load_mode;
@@ -575,6 +583,8 @@ void LLKeyConflictHandler::saveToSettings(bool temporary)
                 break;
             }
 
+            keys.xml_version.set(keybindings_xml_version, true);
+
             if (temporary)
             {
                 // write to temporary xml and use it for gViewerInput
@@ -667,13 +677,19 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 i
     {
         return;
     }
+    LLKeyConflict &type_data = mControlsMap[control_name];
+    if (!type_data.mAssignable)
+    {
+        return;
+    }
     LLKeyData data = getDefaultControl(control_name, index);
 
-    if (data != mControlsMap[control_name].getKeyData(index))
+    if (data != type_data.getKeyData(index))
     {
         // reset controls that might have been switched to our current control
         removeConflicts(data, mControlsMap[control_name].mConflictMask);
         mControlsMap[control_name].setKeyData(data, index);
+        mHasUnsavedChanges = true;
     }
 }
 
@@ -730,9 +746,9 @@ void LLKeyConflictHandler::resetToDefault(const std::string &control_name)
     resetToDefaultAndResolve(control_name, false);
 }
 
-void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
+void LLKeyConflictHandler::resetToDefaultsAndResolve()
 {
-    if (mode == MODE_SAVED_SETTINGS)
+    if (mLoadMode == MODE_SAVED_SETTINGS)
     {
         control_map_t::iterator iter = mControlsMap.begin();
         control_map_t::iterator end = mControlsMap.end();
@@ -745,8 +761,16 @@ void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
     else
     {
         mControlsMap.clear();
-        generatePlaceholders(mode);
+
+        // Set key combinations.
+        // Copy from mDefaultsMap before doing generatePlaceholders, otherwise
+        // insert() will fail to add some keys into pre-existing values from
+        // generatePlaceholders()
         mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+
+        // Set conflict masks and mark functions (un)assignable
+        generatePlaceholders(mLoadMode);
+
     }
 
     mHasUnsavedChanges = true;
@@ -756,7 +780,7 @@ void LLKeyConflictHandler::resetToDefaults()
 {
     if (!empty())
     {
-        resetToDefaults(mLoadMode);
+        resetToDefaultsAndResolve();
     }
     else
     {
@@ -766,7 +790,7 @@ void LLKeyConflictHandler::resetToDefaults()
         // 3. We are loading 'current' only to replace it
         // but it is reliable and works Todo: consider optimizing.
         loadFromSettings(mLoadMode);
-        resetToDefaults(mLoadMode);
+        resetToDefaultsAndResolve();
     }
 }
 
@@ -799,7 +823,7 @@ void LLKeyConflictHandler::resetKeyboardBindings()
 
 void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
 {
-    // These controls are meant to cause conflicts when user tries to assign same control somewhere else
+    // These placeholders are meant to cause conflict resolution when user tries to assign same control somewhere else
     // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks
 
     if (load_mode == MODE_FIRST_PERSON)
@@ -859,24 +883,60 @@ void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
         registerTemporaryControl("spin_around_ccw_sitting");
         registerTemporaryControl("spin_around_cw_sitting");
     }
+
+
+    // Special case, mouse clicks passed to scripts have 'lowest' piority
+    // thus do not conflict, everything else has a chance before them
+    // also in ML they have highest priority, but only when script-grabbed,
+    // thus do not conflict
+    // (see AGENT_CONTROL_ML_LBUTTON_DOWN and CONTROL_LBUTTON_DOWN_INDEX)
+    LLKeyConflict *type_data = &mControlsMap[script_mouse_handler_name];
+    type_data->mAssignable = true;
+    type_data->mConflictMask = U32_MAX - CONFLICT_LMOUSE;
 }
 
-bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask)
+bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, U32 conlict_mask)
 {
     if (conlict_mask == CONFLICT_NOTHING)
     {
         // Can't conflict
         return true;
     }
+
+    if (data.mMouse == CLICK_LEFT
+        && data.mMask == MASK_NONE
+        && data.mKey == KEY_NONE)
+    {
+        if ((conlict_mask & CONFLICT_LMOUSE) == 0)
+        {
+            // Can't conflict
+            return true;
+        }
+        else
+        {
+            // simplify conflict mask
+            conlict_mask = CONFLICT_LMOUSE;
+        }
+    }
+    else
+    {
+        // simplify conflict mask
+        conlict_mask &= ~CONFLICT_LMOUSE;
+    }
+
     std::map<std::string, S32> conflict_list;
     control_map_t::iterator cntrl_iter = mControlsMap.begin();
     control_map_t::iterator cntrl_end = mControlsMap.end();
     for (; cntrl_iter != cntrl_end; ++cntrl_iter)
     {
+        const U32 cmp_mask = cntrl_iter->second.mConflictMask;
+        if ((cmp_mask & conlict_mask) == 0)
+        {
+            // can't conflict
+            continue;
+        }
         S32 index = cntrl_iter->second.mKeyBind.findKeyData(data);
-        if (index >= 0
-            && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING
-            && (cntrl_iter->second.mConflictMask & conlict_mask) != 0)
+        if (index >= 0)
         {
             if (cntrl_iter->second.mAssignable)
             {
diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h
index 2926ca3aeb10f33f9ed3b7aaed53e78bf596579b..23c1adf1e4b16dab2ea423f1eeb03ff6f49ca661 100644
--- a/indra/newview/llkeyconflict.h
+++ b/indra/newview/llkeyconflict.h
@@ -66,6 +66,7 @@ class LLKeyConflictHandler
     };
 
     const U32 CONFLICT_NOTHING = 0;
+    const U32 CONFLICT_LMOUSE = 0x1 << 1;
     // at the moment this just means that key will conflict with everything that is identical
     const U32 CONFLICT_ANY = U32_MAX;
 
@@ -128,23 +129,24 @@ class LLKeyConflictHandler
     // resets current mode to defaults
     void resetToDefaults();
 
-    bool empty() { return mControlsMap.empty(); }
+    bool empty() const { return mControlsMap.empty(); }
     void clear();
 
     // reloads bindings from last valid user's xml or from default xml
     // to keyboard's handler
     static void resetKeyboardBindings();
 
-    bool hasUnsavedChanges() { return mHasUnsavedChanges; }
+    bool hasUnsavedChanges() const { return mHasUnsavedChanges; }
     void setLoadMode(ESourceMode mode) { mLoadMode = mode; }
-    ESourceMode getLoadMode() { return mLoadMode; }
+    ESourceMode getLoadMode() const { return mLoadMode; }
 
 private:
     void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts);
-    void resetToDefaults(ESourceMode mode);
+    void resetToDefaultsAndResolve();
 
     // at the moment these kind of control is not savable, but takes part in conflict resolution
     void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask);
+    // conflict mask 0 means that any conflicts will be ignored
     void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0);
 
     typedef std::map<std::string, LLKeyConflict> control_map_t;
@@ -152,7 +154,7 @@ class LLKeyConflictHandler
     bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);
     void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values
     // returns false in case user is trying to reuse control that can't be reassigned
-    bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask);
+    bool removeConflicts(const LLKeyData &data, U32 conlict_mask);
 
     // removes flags and removes temporary file, returns 'true' if file was removed
     bool clearUnsavedChanges();
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 267f1d03eafb5134f343e885137874bff0ac8909..a3d0eb579624e18e65e5dcc6cab6c6463fcc6545 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -166,13 +166,12 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
 	//requested_options.append("inventory-meat");
 	//requested_options.append("inventory-skel-targets");
 #if (!defined LL_MINIMIAL_REQUESTED_OPTIONS)
-	if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary"))
-	{
-		requested_options.append("inventory-lib-root");
-		requested_options.append("inventory-lib-owner");
-		requested_options.append("inventory-skel-lib");
+
+    // Not requesting library will trigger mFatalNoLibraryRootFolder
+	requested_options.append("inventory-lib-root");
+	requested_options.append("inventory-lib-owner");
+	requested_options.append("inventory-skel-lib");
 	//	requested_options.append("inventory-meat-lib");
-	}
 
 	requested_options.append("initial-outfit");
 	requested_options.append("gestures");
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 5393d0b0b782f3fbf1c66ed2003982b26fb077b4..9142aadab9ff71d78b42019927fb88b10d0d8c8e 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1146,6 +1146,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
             }
             else
             {
+                // Media might be blocked, waiting for a file,
+                // send an empty response to unblock it
+                const std::vector<std::string> empty_response;
+                self->sendPickFileResponse(empty_response);
+
                 LLNotificationsUtil::add("MediaFileDownloadUnsupported");
             }
 		};
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 6b50e1f800c8f64536f87be6f6b9f52f568cc1f9..fef169cbbc3200f75712d7cf510d20d69bfab8ab 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -2549,7 +2549,9 @@ void LLModelPreview::lookupLODModelFiles(S32 lod)
 
     std::string lod_filename = mLODFile[LLModel::LOD_HIGH];
     std::string ext = ".dae";
-    std::string::size_type i = lod_filename.rfind(ext);
+    std::string lod_filename_lower(lod_filename);
+    LLStringUtil::toLower(lod_filename_lower);
+    std::string::size_type i = lod_filename_lower.rfind(ext);
     if (i != std::string::npos)
     {
         lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext);
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index cb4c07a417bb3d9ab012f8d9a54f9f7975431443..852b39f4429ceb806c69b7ec6878e771320a2b50 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -61,7 +61,7 @@
 
 #define CAP_SERVICE_NAVMESH_STATUS          "NavMeshGenerationStatus"
 
-#define CAP_SERVICE_OBJECT_LINKSETS         "ObjectNavMeshProperties"
+#define CAP_SERVICE_OBJECT_LINKSETS         "RegionObjects"
 #define CAP_SERVICE_TERRAIN_LINKSETS        "TerrainNavMeshProperties"
 
 #define CAP_SERVICE_CHARACTERS              "CharacterProperties"
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 061ecad099af5eda3d235b6964624f51486c47a8..39cdb6fb04fbdf355ae79ef54516cde07d09ec2d 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -1029,7 +1029,6 @@ void LLPreviewGesture::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId)
     // active map with the new pointer.				
     if (LLGestureMgr::instance().isGestureActive(itemId))
     {
-        //*TODO: This is crashing for some reason.  Fix it.
         // Active gesture edited from menu.
         LLGestureMgr::instance().replaceGesture(itemId, newAssetId);
         gInventory.notifyObservers();
diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp
index 1119e80005ecaee81ff95099a46f9f3d493b4063..620bbdfcdf91ba60d4d4dbd82d43b1f8088b2c05 100644
--- a/indra/newview/llsearchableui.cpp
+++ b/indra/newview/llsearchableui.cpp
@@ -132,8 +132,11 @@ void ll::statusbar::SearchableItem::setNotHighlighted( )
 	{
 		mCtrl->setHighlighted( false );
 
-		if( mWasHiddenBySearch )
-			mMenu->setVisible( TRUE );
+        if (mWasHiddenBySearch)
+        {
+            mMenu->setVisible(TRUE);
+            mWasHiddenBySearch = false;
+        }
 	}
 }
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3f825e4e43fb4c264de94d3b237699d2a61cc167..8b4c91615c8a95cf69f986655802ae02d22a56e5 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2223,10 +2223,6 @@ bool idle_startup()
 
 		// Have the agent start watching the friends list so we can update proxies
 		gAgent.observeFriends();
-		if (gSavedSettings.getBOOL("LoginAsGod"))
-		{
-			gAgent.requestEnterGodMode();
-		}
 		
 		// Start automatic replay if the flag is set.
 		if (gSavedSettings.getBOOL("StatsAutoRun") || gAgentPilot.getReplaySession())
@@ -2730,19 +2726,34 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 
 	gAgentAvatarp->setSex(gender);
 
-	// try to find the outfit - if not there, create some default
-	// wearables.
+	// try to find the requested outfit or folder
+
+	// -- check for existing outfit in My Outfits
+	bool do_copy = false;
 	LLUUID cat_id = findDescendentCategoryIDByName(
-		gInventory.getLibraryRootFolderID(),
+		gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS),
 		outfit_folder_name);
+
+	// -- check for existing folder in Library
+	if (cat_id.isNull())
+	{
+		cat_id = findDescendentCategoryIDByName(
+			gInventory.getLibraryRootFolderID(),
+			outfit_folder_name);
+		if (!cat_id.isNull())
+		{
+			do_copy = true;
+		}
+	}
+
 	if (cat_id.isNull())
 	{
+		// -- final fallback: create standard wearables
 		LL_DEBUGS() << "standard wearables" << LL_ENDL;
 		gAgentWearables.createStandardWearables();
 	}
 	else
 	{
-		bool do_copy = true;
 		bool do_append = false;
 		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
 		// Need to fetch cof contents before we can wear.
@@ -3617,6 +3628,19 @@ bool process_login_success_response()
 		}
 	}
 
+	std::string fake_initial_outfit_name = gSavedSettings.getString("FakeInitialOutfitName");
+	if (!fake_initial_outfit_name.empty())
+	{
+		gAgent.setFirstLogin(TRUE);
+		sInitialOutfit = fake_initial_outfit_name;
+		if (sInitialOutfitGender.empty())
+		{
+			sInitialOutfitGender = "female"; // just guess, will get overridden when outfit is worn anyway.
+		}
+
+		LL_WARNS() << "Faking first-time login with initial outfit " << sInitialOutfit << LL_ENDL;
+	}
+
 	// set the location of the Agent Appearance service, from which we can request
 	// avatar baked textures if they are supported by the current region
 	std::string agent_appearance_url = response["agent_appearance_service"];
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index ba328f27c4cf81640f781bda2e4935e26ebd010c..6d54a3770ce425aabf22a95133b7fecb954a6828 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -44,6 +44,7 @@
 #include "lltoolmgr.h"
 #include "lltoolselectrect.h"
 #include "lltoolplacer.h"
+#include "llviewerinput.h"
 #include "llviewermenu.h"
 #include "llviewerobject.h"
 #include "llviewerwindow.h"
@@ -745,7 +746,7 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)
 BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
 { 
 	// if the left button is grabbed, don't put up the pie menu
-	if (gAgent.leftButtonGrabbed())
+	if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
 	{
 		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
 		return FALSE;
@@ -762,7 +763,7 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
 BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
 	// if the left button is grabbed, don't put up the pie menu
-	if (gAgent.leftButtonGrabbed())
+	if (gAgent.leftButtonGrabbed() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
 	{
 		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
 		return FALSE;
@@ -796,7 +797,10 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
+    if (gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
+    {
+        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
+    }
 	setCurrentTool( (LLTool*) mGun );
 	return TRUE;
 }
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index f01b374db117fe9f4789959ff8ca96a2844eb194..7ab079c74dbecd440260f9dc60fe95e1bf11200f 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -51,6 +51,7 @@
 #include "lltoolmgr.h"
 #include "lltoolpie.h"
 #include "llviewercamera.h"
+#include "llviewerinput.h"
 #include "llviewerobject.h"
 #include "llviewerobjectlist.h" 
 #include "llviewerregion.h"
@@ -140,7 +141,6 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
 		LL_INFOS() << "LLToolGrab handleMouseDown" << LL_ENDL;
 	}
 
-	// call the base class to propogate info to sim
 	LLTool::handleMouseDown(x, y, mask);
 
 	// leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account
@@ -150,6 +150,19 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
 		gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
 	}
 	mClickedInMouselook = gAgentCamera.cameraMouselook();
+
+    if (mClickedInMouselook && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
+    {
+        // LLToolCompGun::handleMouseDown handles the event if ML controls are grabed,
+        // but LLToolGrabBase is often the end point for mouselook clicks if ML controls
+        // are not grabbed and LLToolGrabBase::handleMouseDown consumes the event,
+        // so send clicks from here.
+        // We are sending specifically CONTROL_LBUTTON_DOWN instead of _ML_ version.
+        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
+
+        // Todo: LLToolGrabBase probably shouldn't consume the event if there is nothing
+        // to grab in Mouselook, it intercepts handling in scanMouse
+    }
 	return TRUE;
 }
 
@@ -953,9 +966,18 @@ void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask)
 
 BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	// call the base class to propogate info to sim
 	LLTool::handleMouseUp(x, y, mask);
 
+    if (gAgentCamera.cameraMouselook() && gViewerInput.isLMouseHandlingDefault(MODE_FIRST_PERSON))
+    {
+        // LLToolCompGun::handleMouseUp handles the event if ML controls are grabed,
+        // but LLToolGrabBase is often the end point for mouselook clicks if ML controls
+        // are not grabbed and LToolGrabBase::handleMouseUp consumes the event,
+        // so send clicks from here.
+        // We are sending specifically CONTROL_LBUTTON_UP instead of _ML_ version.
+        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
+    }
+
 	if( hasMouseCapture() )
 	{
 		setMouseCapture( FALSE );
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index b4736841d639ed2287bf690ef4f89831dbf3b742..43deac60d92188f1bc5a0017b43aa416593084a4 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -394,8 +394,9 @@ BOOL LLToolPie::handleLeftClickPick()
 		gFocusMgr.setKeyboardFocus(NULL);
 	}
 
-	BOOL touchable = (object && object->flagHandleTouch()) 
-					 || (parent && parent->flagHandleTouch());
+    bool touchable = object
+                     && (object->getClickAction() != CLICK_ACTION_DISABLED)
+                     && (object->flagHandleTouch() || (parent && parent->flagHandleTouch()));
 
 	// Switch to grab tool if physical or triggerable
 	if (object && 
@@ -656,6 +657,12 @@ bool LLToolPie::teleportToClickedLocation()
     LLViewerObject* objp = mHoverPick.getObject();
     LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
 
+    if (objp && (objp->getAvatar() == gAgentAvatarp || objp == gAgentAvatarp)) // ex: nametag
+    {
+        // Don't teleport to self, teleporting to other avatars is fine
+        return false;
+    }
+
     bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
     bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND;
     bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero();
@@ -750,7 +757,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 	else if (!mMouseOutsideSlop 
 		&& mMouseButtonDown
 		// disable camera steering if click on land is not used for moving
-		&& gViewerInput.isMouseBindUsed(CLICK_LEFT))
+		&& gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON))
 	{
 		S32 delta_x = x - mMouseDownX;
 		S32 delta_y = y - mMouseDownY;
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 6aa12731749fcd90ddd84d93d467a95e5bf9b9bb..70065cb5a049698ba081585cd3cdf9076711d33a 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -353,7 +353,7 @@ void LLViewerAssetStorage::checkForTimeouts()
     // Restore requests
     LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
     while (mCoroWaitList.size() > 0
-           && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+           && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
     {
         CoroWaitList &request = mCoroWaitList.front();
         
@@ -425,13 +425,14 @@ void LLViewerAssetStorage::queueRequestHttp(
     if (!duplicate)
     {
         // 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)
+        LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
+        if (manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
         {
             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",
+            manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
                 boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
         }
         else
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 94ec5347322c17e5dab24db59509d9f248c28170..43b9cd90bd6f90cdfb3917dff2acb79920ff2c90 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -816,13 +816,20 @@ bool toggle_enable_media(EKeystate s)
 
 bool walk_to(EKeystate s)
 {
-    if (KEYSTATE_DOWN != s) return true;
+    if (KEYSTATE_DOWN != s)
+    {
+        // teleport/walk is usually on mouseclick, mouseclick needs
+        // to let AGENT_CONTROL_LBUTTON_UP happen if teleport didn't,
+        // so return false, but if it causes issues, do some kind of
+        // "return !has_teleported"
+        return false;
+    }
     return LLToolPie::getInstance()->walkToClickedLocation();
 }
 
 bool teleport_to(EKeystate s)
 {
-    if (KEYSTATE_DOWN != s) return true;
+    if (KEYSTATE_DOWN != s) return false;
     return LLToolPie::getInstance()->teleportToClickedLocation();
 }
 
@@ -850,7 +857,47 @@ bool voice_follow_key(EKeystate s)
     return false;
 }
 
-bool agen_control_lbutton_handle(EKeystate s)
+bool script_trigger_lbutton(EKeystate s)
+{
+    // Check for script overriding/expecting left mouse button.
+    // Note that this does not pass event further and depends onto mouselook.
+    // Checks CONTROL_ML_LBUTTON_DOWN_INDEX for mouselook,
+    // CONTROL_LBUTTON_DOWN_INDEX for normal camera
+    if (gAgent.leftButtonGrabbed())
+    {
+        bool mouselook = gAgentCamera.cameraMouselook();
+        switch (s)
+        {
+        case KEYSTATE_DOWN:
+            if (mouselook)
+            {
+                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
+            }
+            else
+            {
+                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
+            }
+            return true;
+        case KEYSTATE_UP:
+            if (mouselook)
+            {
+                gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
+            }
+            else
+            {
+                gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
+            }
+            return true;
+        default:
+            break;
+        }
+    }
+    return false;
+}
+
+// Used by scripts, for overriding/handling left mouse button
+// see mControlsTakenCount
+bool agent_control_lbutton_handle(EKeystate s)
 {
     switch (s)
     {
@@ -922,6 +969,7 @@ REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);
 REGISTER_KEYBOARD_ACTION("walk_to", walk_to);
 REGISTER_KEYBOARD_GLOBAL_ACTION("toggle_voice", toggle_voice);
 REGISTER_KEYBOARD_GLOBAL_ACTION("voice_follow_key", voice_follow_key);
+REGISTER_KEYBOARD_ACTION(script_mouse_handler_name, script_trigger_lbutton);
 #undef REGISTER_KEYBOARD_ACTION
 
 LLViewerInput::LLViewerInput()
@@ -1193,6 +1241,20 @@ BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const
     typedef boost::function<bool(EKeystate)> function_t;
     function_t function = NULL;
 
+    if (mouse == CLICK_LEFT
+        && mask == MASK_NONE
+        && function_name == script_mouse_handler_name)
+    {
+        // Special case
+        // Left click has script overrides and by default
+        // is handled via agent_control_lbutton as last option
+        // In case of mouselook and present overrides it has highest
+        // priority even over UI and is handled in LLToolCompGun::handleMouseDown
+        // so just mark it as having default handler
+        mLMouseDefaultHandling[mode] = true;
+        return TRUE;
+    }
+
     LLKeybindFunctionData* result = LLKeyboardActionRegistry::getValue(function_name);
     if (result)
     {
@@ -1269,7 +1331,8 @@ LLViewerInput::Keys::Keys()
 :	first_person("first_person"),
 	third_person("third_person"),
 	sitting("sitting"),
-	edit_avatar("edit_avatar")
+	edit_avatar("edit_avatar"),
+	xml_version("xml_version", 0)
 {}
 
 void LLViewerInput::resetBindings()
@@ -1280,6 +1343,7 @@ void LLViewerInput::resetBindings()
         mGlobalMouseBindings[i].clear();
         mKeyBindings[i].clear();
         mMouseBindings[i].clear();
+        mLMouseDefaultHandling[i] = false;
     }
 }
 
@@ -1298,6 +1362,65 @@ S32 LLViewerInput::loadBindingsXML(const std::string& filename)
 		binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON);
 		binding_count += loadBindingMode(keys.sitting, MODE_SITTING);
 		binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR);
+
+        // verify version
+        if (keys.xml_version < 1)
+        {
+            // updating from a version that was not aware of LMouse bindings
+            for (S32 i = 0; i < MODE_COUNT; i++)
+            {
+                mLMouseDefaultHandling[i] = true;
+            }
+
+            // fix missing values
+            KeyBinding mouse_binding;
+            mouse_binding.key = "";
+            mouse_binding.mask = "NONE";
+            mouse_binding.mouse = "LMB";
+            mouse_binding.command = script_mouse_handler_name;
+
+            if (keys.third_person.isProvided())
+            {
+                keys.third_person.bindings.add(mouse_binding);
+            }
+
+            if (keys.first_person.isProvided())
+            {
+                keys.first_person.bindings.add(mouse_binding);
+            }
+
+            if (keys.sitting.isProvided())
+            {
+                keys.sitting.bindings.add(mouse_binding);
+            }
+
+            if (keys.edit_avatar.isProvided())
+            {
+                keys.edit_avatar.bindings.add(mouse_binding);
+            }
+
+            // fix version
+            keys.xml_version.set(keybindings_xml_version, true);
+
+            // Write the resulting XML to file
+            LLXMLNodePtr output_node = new LLXMLNode("keys", false);
+            LLXUIParser write_parser;
+            write_parser.writeXUI(output_node, keys);
+
+            if (!output_node->isNull())
+            {
+                // file in app_settings is supposed to be up to date
+                // this is only for the file from user_settings
+                LL_INFOS("ViewerInput") << "Updating file " << filename << " to a newer version" << LL_ENDL;
+                LLFILE *fp = LLFile::fopen(filename, "w");
+                if (fp != NULL)
+                {
+                    LLXMLNode::writeHeaderToFile(fp);
+                    output_node->writeToFile(fp);
+                    fclose(fp);
+                }
+            }
+        }
 	}
 	return binding_count;
 }
@@ -1469,17 +1592,6 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
 
     bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat);
 
-    if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask))
-    {
-        if (key_down && !repeat)
-        {
-            res = agen_control_lbutton_handle(KEYSTATE_DOWN);
-        }
-        if (key_up)
-        {
-            res = agen_control_lbutton_handle(KEYSTATE_UP);
-        }
-    }
     return res;
 }
 
@@ -1603,29 +1715,36 @@ bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const
     bool res = false;
     S32 mode = getMode();
     MASK mask = gKeyboard->currentMask(TRUE);
-
-    // By default mouse clicks require exact mask
-    // Todo: support for mIgnoreMasks because some functions like teleports
-    // expect to be canceled, but for voice it's prefered to ignore mask.
     res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state, false);
-    // no user defined actions found or those actions can't handle the key/button, handle control if nessesary
-    if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask))
+
+    // No user defined actions found or those actions can't handle the key/button,
+    // so handle CONTROL_LBUTTON if nessesary.
+    //
+    // Default handling for MODE_FIRST_PERSON is in LLToolCompGun::handleMouseDown,
+    // and sends AGENT_CONTROL_ML_LBUTTON_DOWN, but it only applies if ML controls
+    // are leftButtonGrabbed(), send a normal click otherwise.
+
+    if (!res
+        && mLMouseDefaultHandling[mode]
+        && (mode != MODE_FIRST_PERSON || !gAgent.leftButtonGrabbed())
+        && (click == CLICK_LEFT || click == CLICK_DOUBLELEFT)
+        )
     {
         switch (state)
         {
         case MOUSE_STATE_DOWN:
-            agen_control_lbutton_handle(KEYSTATE_DOWN);
+            agent_control_lbutton_handle(KEYSTATE_DOWN);
             res = true;
             break;
         case MOUSE_STATE_CLICK:
             // might not work best with some functions,
             // but some function need specific states too specifically
-            agen_control_lbutton_handle(KEYSTATE_DOWN);
-            agen_control_lbutton_handle(KEYSTATE_UP);
+            agent_control_lbutton_handle(KEYSTATE_DOWN);
+            agent_control_lbutton_handle(KEYSTATE_UP);
             res = true;
             break;
         case MOUSE_STATE_UP:
-            agen_control_lbutton_handle(KEYSTATE_UP);
+            agent_control_lbutton_handle(KEYSTATE_UP);
             res = true;
             break;
         default:
@@ -1655,7 +1774,7 @@ void LLViewerInput::scanMouse()
     }
 }
 
-bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode)
+bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const
 {
     S32 size = mMouseBindings[mode].size();
     for (S32 index = 0; index < size; index++)
diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h
index ca70ac76bf0f294c8655850efd94e3f07b879171..52e95e2168ba4103891e58ae9a9e6267cc328ebd 100644
--- a/indra/newview/llviewerinput.h
+++ b/indra/newview/llviewerinput.h
@@ -31,6 +31,8 @@
 #include "llinitparam.h"
 
 const S32 MAX_KEY_BINDINGS = 128; // was 60
+const S32 keybindings_xml_version = 1;
+const std::string script_mouse_handler_name = "script_trigger_lbutton";
 
 class LLNamedFunction
 {
@@ -100,7 +102,7 @@ class LLViewerInput
 							third_person,
 							sitting,
 							edit_avatar;
-
+		Optional<S32> xml_version; // 'xml', because 'version' appears to be reserved
 		Keys();
 	};
 
@@ -131,7 +133,8 @@ class LLViewerInput
     BOOL            handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
     void            scanMouse();
 
-    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON);
+    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode) const;
+    bool            isLMouseHandlingDefault(const S32 mode) const { return mLMouseDefaultHandling[mode]; }
 
 private:
     bool            scanKey(const std::vector<LLKeyboardBinding> &binding,
@@ -171,6 +174,7 @@ class LLViewerInput
     // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown)
     std::vector<LLKeyboardBinding>	mKeyBindings[MODE_COUNT];
     std::vector<LLMouseBinding>		mMouseBindings[MODE_COUNT];
+    bool							mLMouseDefaultHandling[MODE_COUNT]; // Due to having special priority
 
     // keybindings that do not consume event and are handled earlier, before floaters
     std::vector<LLKeyboardBinding>	mGlobalKeyBindings[MODE_COUNT];
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 07190d0538f3aeaee3e0df9a58fc53eb9735d9a1..29c926ca64e81703a9a764674a6459be179aab57 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -3198,10 +3198,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 		case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD:
 		{
 			LL_DEBUGS("Media") << "Media event - file download requested - filename is " << plugin->getFileDownloadFilename() << LL_ENDL;
-
-            //unblock media plugin
-            const std::vector<std::string> empty_response;
-            plugin->sendPickFileResponse(empty_response);
 		}
 		break;
 
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 31e80eb8655041a69b1da519ee8f67eaa06a8254..4c476e89ce0fc086d66570614e626ed059a0fc15 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -1264,6 +1264,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 				mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE);
 
 				mTotalCRC = crc;
+                // Might need to update mSourceMuted here to properly pick up new radius
 				mSoundCutOffRadius = cutoff;
 
 				// Owner ID used for sound muting or particle system muting
@@ -5873,7 +5874,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
 		else if (flags & LL_SOUND_FLAG_STOP)
         {
 			// Just shut off the sound
-			mAudioSourcep->play(LLUUID::null);
+			mAudioSourcep->stop();
 		}
 		return;
 	}
@@ -5912,7 +5913,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
 		mAudioSourcep->setQueueSounds(queue);
 		if(!queue) // stop any current sound first to avoid "farts of doom" (SL-1541) -MG
 		{
-			mAudioSourcep->play(LLUUID::null);
+			mAudioSourcep->stop();
 		}
 		
 		// Play this sound if region maturity permits
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 27fbf39673a044c5b311c8a762f4269aa2aa6b95..2fb760ed178575600c197dca607db068b05928d4 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -3008,12 +3008,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("ObjectAnimation");
 	capabilityNames.append("ObjectMedia");
 	capabilityNames.append("ObjectMediaNavigate");
-	capabilityNames.append("ObjectNavMeshProperties");
 	capabilityNames.append("ParcelPropertiesUpdate");
 	capabilityNames.append("ParcelVoiceInfoRequest");
 	capabilityNames.append("ProductInfoRequest");
 	capabilityNames.append("ProvisionVoiceAccountRequest");
 	capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite
+	capabilityNames.append("RegionObjects");
 	capabilityNames.append("RemoteParcelRequest");
 	capabilityNames.append("RenderMaterials");
 	capabilityNames.append("RequestTextureDownload");
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 050fb454ad37e36d41faae651c990ee0c4306f1f..9334fa5c76ddaa219a82c8fdae95770585c7cce9 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2291,6 +2291,9 @@ void LLViewerWindow::initWorldUI()
 	LLPanelStandStopFlying* panel_stand_stop_flying	= LLPanelStandStopFlying::getInstance();
 	panel_ssf_container->addChild(panel_stand_stop_flying);
 
+	LLPanelHideBeacon* panel_hide_beacon = LLPanelHideBeacon::getInstance();
+	panel_ssf_container->addChild(panel_hide_beacon);
+
 	panel_ssf_container->setVisible(TRUE);
 
 	LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 5d994058c2e0ddf7cb253ffbc1e77dadd5ca644f..d421b3b1f65212d512a96a5b595f06bd82ece0e3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1323,7 +1323,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
 {
     LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);
 
-    S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
+    static LLCachedControl<S32> box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity");
+    S32 box_detail = box_detail_cache;
     if (getOverallAppearance() != AOA_NORMAL)
     {
         if (isControlAvatar())
@@ -2532,10 +2533,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 	{
 		LL_INFOS() << "Warning!  Idle on dead avatar" << LL_ENDL;
 		return;
-	}	
+	}
 
+	static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
 	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
-		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf())
+		&& !disable_all_render_types && !isSelf())
 	{
 		return;
 	}
@@ -2676,7 +2678,8 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 	// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
 	if(isSelf())
 	{
-		if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("VoiceDisableMic"))
+        static LLCachedControl<bool> voice_disable_mic(gSavedSettings, "VoiceDisableMic");
+		if(gAgentCamera.cameraMouselook() || voice_disable_mic)
 		{
 			render_visualizer = false;
 		}
@@ -3145,11 +3148,14 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 	}
 	
 	const F32 time_visible = mTimeVisible.getElapsedTimeF32();
-	const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime");	// seconds
-	const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds
-	BOOL visible_avatar = isVisible() || mNeedsAnimUpdate;
-	BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping);
-	BOOL render_name =	visible_chat ||
+
+    static LLCachedControl<F32> NAME_SHOW_TIME(gSavedSettings, "RenderNameShowTime"); // seconds
+    static LLCachedControl<F32> FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds
+    static LLCachedControl<bool> use_chat_bubbles(gSavedSettings, "UseChatBubbles");
+
+	bool visible_avatar = isVisible() || mNeedsAnimUpdate;
+	bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping);
+	bool render_name =	visible_chat ||
 		(visible_avatar &&
 		 ((sRenderName == RENDER_NAME_ALWAYS) ||
 		  (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
@@ -3157,10 +3163,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 	// draw if we're specifically hiding our own name.
 	if (isSelf())
 	{
+        static LLCachedControl<bool> render_name_show_self(gSavedSettings, "RenderNameShowSelf");
+        static LLCachedControl<S32> name_tag_mode(gSavedSettings, "AvatarNameTagMode");
 		render_name = render_name
 			&& !gAgentCamera.cameraMouselook()
-			&& (visible_chat || (gSavedSettings.getBOOL("RenderNameShowSelf") 
-								 && gSavedSettings.getS32("AvatarNameTagMode") ));
+			&& (visible_chat || (render_name_show_self && name_tag_mode));
 	}
 
 	if ( !render_name )
@@ -3175,7 +3182,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-	BOOL new_name = FALSE;
+	bool new_name = FALSE;
 	if (visible_chat != mVisibleChat)
 	{
 		mVisibleChat = visible_chat;
@@ -3240,7 +3247,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 	idleUpdateNameTagAlpha(new_name, alpha);
 }
 
-void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
+void LLVOAvatar::idleUpdateNameTagText(bool new_name)
 {
 	LLNameValue *title = getNVPair("Title");
 	LLNameValue* firstname = getNVPair("FirstName");
@@ -3550,7 +3557,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 	mNameText->setPositionAgent(name_position);				
 }
 
-void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
+void LLVOAvatar::idleUpdateNameTagAlpha(bool new_name, F32 alpha)
 {
 	llassert(mNameText);
 
@@ -3693,7 +3700,8 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
 		{
 			debug_line += llformat(" - cof: %d req: %d rcv:%d",
 								   curr_cof_version, last_request_cof_version, last_received_cof_version);
-			if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+			static LLCachedControl<bool> debug_force_failure(gSavedSettings, "DebugForceAppearanceRequestFailure");
+			if (debug_force_failure)
 			{
 				debug_line += " FORCING ERRS";
 			}
@@ -5927,7 +5935,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
 					//}
 					//else
 					{
-						LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
+                        static LLCachedControl<std::string> ui_snd_string(gSavedSettings, "UISndTyping");
+						LLUUID sound_id = LLUUID(ui_snd_string);
 						gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global);
 					}
 				}
@@ -5995,7 +6004,7 @@ void LLVOAvatar::resetAnimations()
 // animations.
 LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
 {
-	BOOL use_new_walk_run = gSavedSettings.getBOOL("UseNewWalkRun");
+    static LLCachedControl<bool> use_new_walk_run(gSavedSettings, "UseNewWalkRun");
 	LLUUID result = id;
 
 	// start special case female walk for female avatars
@@ -8183,7 +8192,8 @@ BOOL LLVOAvatar::isFullyLoaded() const
 bool LLVOAvatar::isTooComplex() const
 {
 	bool too_complex;
-	bool render_friend =  (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends"));
+    static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends");
+	bool render_friend =  (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends);
 
 	if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
 	{
@@ -9036,7 +9046,8 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
 	
 	// Parse visual params, if any.
 	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
-	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
+    static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams");
+	bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
 	if( num_blocks > 1 && !drop_visual_params_debug)
 	{
 		//LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
@@ -9141,10 +9152,12 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32
 void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 {
 	LL_DEBUGS("Avatar") << "starts" << LL_ENDL;
-	
-	bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+
+    static LLCachedControl<bool> enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage");
+    static LLCachedControl<bool> block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages");
+
 	std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
-	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
+	if (block_avatar_appearance_messages)
 	{
 		LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL;
 		return;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 74ef589ca47a9532e7fc242c9d9e67fbf2acdf36..96a8372188738ff949d25d3d7af0eeab5f0b01af 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -284,9 +284,9 @@ class LLVOAvatar :
 	void 			idleUpdateLoadingEffect();
 	void 			idleUpdateWindEffect();
 	void 			idleUpdateNameTag(const LLVector3& root_pos_last);
-	void			idleUpdateNameTagText(BOOL new_name);
+	void			idleUpdateNameTagText(bool new_name);
 	void			idleUpdateNameTagPosition(const LLVector3& root_pos_last);
-	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
+	void			idleUpdateNameTagAlpha(bool new_name, F32 alpha);
 	LLColor4		getNameTagColor(bool is_friend);
 	void			clearNameTag();
 	static void		invalidateNameTag(const LLUUID& agent_id);
@@ -908,7 +908,7 @@ class LLVOAvatar :
 	void	   		startTyping() { mTyping = TRUE; mTypingTimer.reset(); }
 	void			stopTyping() { mTyping = FALSE; }
 private:
-	BOOL			mVisibleChat;
+	bool			mVisibleChat;
 
 	//--------------------------------------------------------------------
 	// Lip synch morphs
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 77f756a1230d88dd07f61bac619bc91cf44a8c4b..d75a4fd42d3589310dcd25b88f123e38e8b24791 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -71,6 +71,8 @@
 #include "llmediaentry.h"
 #include "llmediadataclient.h"
 #include "llmeshrepository.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
 #include "llagent.h"
 #include "llviewermediafocus.h"
 #include "lldatapacker.h"
@@ -2960,6 +2962,17 @@ void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin,
 			}
 		}
 		break;
+
+        case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD:
+        {
+            // Media might be blocked, waiting for a file,
+            // send an empty response to unblock it
+            const std::vector<std::string> empty_response;
+            plugin->sendPickFileResponse(empty_response);
+
+            LLNotificationsUtil::add("MediaFileDownloadUnsupported");
+        }
+        break;
 		
 		default:
 		break;
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index b8f1ec35f6dd707a296fd31dda90a554dcafa987..c4d873dd22bc42c2ec140567f070ae9c5cdc3a65 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -199,19 +199,16 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
 	// find the grid
 	std::string current_grid = LLGridManager::getInstance()->getGridId();
 	std::transform(current_grid.begin(), current_grid.end(), current_grid.begin(), ::tolower);
-	if (current_grid == "agni")
+    if (current_grid == "damballah")
 	{
-		substitution["GRID"] = "secondlife.com";
-	}
-	else if (current_grid == "damballah")
-	{
-		// Staging grid has its own naming scheme.
-		substitution["GRID"] = "secondlife-staging.com";
-	}
-	else
-	{
-		substitution["GRID"] = llformat("%s.lindenlab.com", current_grid.c_str());
-	}
+      // Staging grid has its own naming scheme.
+      substitution["GRID"] = "secondlife-staging.com";
+    }
+    else
+    {
+        substitution["GRID"] = "secondlife.com";
+    }
+
 	// expand all of the substitution strings and escape the url
 	std::string expanded_url = url;
 	LLStringUtil::format(expanded_url, substitution);
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index fb3fc55a94c2813a69b454d046551fd8cbd88dd1..81511ac55596a0d690cfc7a4e5e46ab73de94606 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1195,6 +1195,16 @@ class LLEstablishAgentCommunication : public LLHTTPNode
 	virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const
 	{
         if (LLApp::isExiting())
+        {
+            return;
+        }
+
+        if (gDisconnected)
+        {
+            return;
+        }
+
+        if (!LLWorld::instanceExists())
         {
             return;
         }
@@ -1207,8 +1217,13 @@ class LLEstablishAgentCommunication : public LLHTTPNode
             return;
 		}
 
-		LLHost sim(input["body"]["sim-ip-and-port"].asString());
-	
+        LLHost sim(input["body"]["sim-ip-and-port"].asString());
+        if (sim.isInvalid())
+        {
+            LL_WARNS() << "Got EstablishAgentCommunication with invalid host" << LL_ENDL;
+            return;
+        }
+
 		LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim);
 		if (!regionp)
 		{
@@ -1217,7 +1232,7 @@ class LLEstablishAgentCommunication : public LLHTTPNode
 			return;
 		}
 		LL_DEBUGS("CrossingCaps") << "Calling setSeedCapability from LLEstablishAgentCommunication::post. Seed cap == "
-				<< input["body"]["seed-capability"] << LL_ENDL;
+				<< input["body"]["seed-capability"] << " for region " << regionp->getRegionID() << LL_ENDL;
 		regionp->setSeedCapability(input["body"]["seed-capability"]);
 	}
 };
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_media.xml b/indra/newview/skins/default/xui/en/control_table_contents_media.xml
index ce5d3556b612988e32fab8aa341b334b7e06d132..43e8d730cd9679460d8bf6eeb9277c0d46b3a71e 100644
--- a/indra/newview/skins/default/xui/en/control_table_contents_media.xml
+++ b/indra/newview/skins/default/xui/en/control_table_contents_media.xml
@@ -73,4 +73,14 @@
          name="lst_action"
          value="Start Gesture" />
     </rows>
+    <rows
+     name="script_trigger_lbutton"
+     value="script_trigger_lbutton">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Interact (Script LMB)" />
+    </rows>
 </contents>
diff --git a/indra/newview/skins/default/xui/en/floater_associate_listing.xml b/indra/newview/skins/default/xui/en/floater_associate_listing.xml
index e019ed58ddbd9aa955f65d7e918384246154f24a..0f7ed241034e3aee0c1e1263b564be35deb3fcd5 100644
--- a/indra/newview/skins/default/xui/en/floater_associate_listing.xml
+++ b/indra/newview/skins/default/xui/en/floater_associate_listing.xml
@@ -20,9 +20,10 @@
      name="message">
         Listing ID:
     </text>
+    <!--listing_id is a positive S32-->
     <line_editor
      type="string"
-     length="1"
+     max_length_bytes="10"
      follows="top|right"
      font="SansSerif"
      height="20"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 175698ca41808f44b12b4522efa2dc3d057b5db8..dd8a2cf5fd5d37d23464c1c37080e74d02d06776 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2309,6 +2309,7 @@ Please try again later.
   <notification
    icon="notifytip.tga"
    name="LandmarkCreated"
+   log_to_chat="false"
    type="notifytip">
 You have added "[LANDMARK_NAME]" to your [FOLDER_NAME] folder.
   </notification>
diff --git a/indra/newview/skins/default/xui/en/panel_hide_beacon.xml b/indra/newview/skins/default/xui/en/panel_hide_beacon.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7cab285f77dc37e1cba722b0ad44a6652fe3b6bc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_hide_beacon.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="25"
+ layout="topleft"
+ name="panel_hide_beacon"
+ mouse_opaque="false"
+ visible="true"
+ width="133">
+    <button
+     follows="left|bottom"
+     height="19"
+     label="Hide beacon"
+     layout="topleft"
+     left="10"
+     name="hide_beacon_btn"
+     tool_tip="Stop tracking and hide beacon"
+     top="2"
+     visible="false"
+     width="113" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 2ea20570b18e39da29a3e874ffc58667c90b5fac..42a34d171aa352179d3c04aad6e6b5ca0bc7ebc6 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -28,7 +28,7 @@
      height="15"
      increment="0.025"
      initial_value="0.5"
-     label="Master volume"
+     label="All volume"
 	   label_width="120"
      layout="topleft"
      left="0"
@@ -386,7 +386,7 @@
      left="25"
      name="voice_chat_settings"
      width="200"
-     top_pad="7">
+     top_pad="16">
 	  Voice Chat Settings
     </text>
     <text
diff --git a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
index f5c559fe1dda158c06c33f4439980e9067918200..a3348f28c7317adf250d1de172f3a67174bd7e11 100644
--- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
@@ -95,7 +95,7 @@
                tab_stop="false"
                name="state_management_buttons_container"
                visible="false"
-               width="200"/>
+               width="350"/>
       </layout_panel>
        <layout_panel name="right_toolbar_panel"
                     auto_resize="false"
diff --git a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
index 2034409111990c1550be42693801162092cb9c37..b4eb1ade9476c79fb2b551087810c1e454c0e3ae 100644
--- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
+++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
@@ -19,7 +19,7 @@
      height="15"
      increment="0.025"
      initial_value="0.5"
-     label="Master"
+     label="All"
      label_width="60"
      left="10"
      width="160"
diff --git a/indra/test/sync.h b/indra/test/sync.h
index ca8b7262d692612c7a7f9c656ee67d9e98e59213..bd837cb73054aa1659727288dee80bd6036e0a74 100644
--- a/indra/test/sync.h
+++ b/indra/test/sync.h
@@ -89,25 +89,26 @@ class Sync
     /// suspend until "somebody else" has bumped mCond by n steps
     void yield(int n=1)
     {
-        return yield_until(STRINGIZE("Sync::yield_for(" << n << ") timed out after "
-                                     << int(mTimeout.value()) << "ms"),
-                           mCond.get() + n);
+        return yield_until("Sync::yield_for", n, mCond.get() + n);
     }
 
     /// suspend until "somebody else" has bumped mCond to a specific value
     void yield_until(int until)
     {
-        return yield_until(STRINGIZE("Sync::yield_until(" << until << ") timed out after "
-                                     << int(mTimeout.value()) << "ms"),
-                           until);
+        return yield_until("Sync::yield_until", until, until);
     }
 
 private:
-    void yield_until(const std::string& desc, int until)
+    void yield_until(const char* func, int arg, int until)
     {
         std::string name(llcoro::logname());
         LL_DEBUGS() << name << " yield_until(" << until << ") suspending" << LL_ENDL;
-        tut::ensure(name + ' ' + desc, mCond.wait_for_equal(mTimeout, until));
+        if (! mCond.wait_for_equal(mTimeout, until))
+        {
+            tut::fail(STRINGIZE(name << ' ' << func << '(' << arg << ") timed out after "
+                                << int(mTimeout.value()) << "ms (expected " << until
+                                << ", actual " << mCond.get() << ')'));
+        }
         // each time we wake up, bump mCond
         bump();
     }