From 85c24a489dd0550db253f442fc5e22a6494b7cd7 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 6 Feb 2017 13:04:22 +0200
Subject: MAINT-7104 Add Grid status floater and toolbar button

---
 indra/newview/CMakeLists.txt                       |  2 +
 indra/newview/app_settings/commands.xml            | 10 +++
 indra/newview/app_settings/settings.xml            | 16 +++++
 indra/newview/llfloatergridstatus.cpp              | 84 ++++++++++++++++++++++
 indra/newview/llfloatergridstatus.h                | 56 +++++++++++++++
 indra/newview/llviewerfloaterreg.cpp               |  2 +
 indra/newview/skins/default/textures/textures.xml  |  1 +
 .../skins/default/xui/en/floater_grid_status.xml   | 18 +++++
 indra/newview/skins/default/xui/en/strings.xml     |  2 +
 9 files changed, 191 insertions(+)
 create mode 100644 indra/newview/llfloatergridstatus.cpp
 create mode 100644 indra/newview/llfloatergridstatus.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_grid_status.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9ac1c3520d..dbec4b5d65 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -236,6 +236,7 @@ set(viewer_SOURCE_FILES
     llfloatergesture.cpp
     llfloatergodtools.cpp
     llfloatergotoline.cpp
+    llfloatergridstatus.cpp
     llfloatergroupbulkban.cpp
     llfloatergroupinvite.cpp
     llfloatergroups.cpp
@@ -852,6 +853,7 @@ set(viewer_HEADER_FILES
     llfloatergesture.h
     llfloatergodtools.h
     llfloatergotoline.h
+    llfloatergridstatus.h
     llfloatergroupbulkban.h
     llfloatergroupinvite.h
     llfloatergroups.h
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 9bc0a7c701..64cd11a53a 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -292,4 +292,14 @@
            is_running_function="Floater.IsOpen"
            is_running_parameters="reporter"
            />
+  <command name="gridstatus"
+           available_in_toybox="true"
+           icon="Command_Grid_Status_Icon"
+           label_ref="Command_Grid_Status_Label"
+           tooltip_ref="Command_Grid_Status_Tooltip"
+           execute_function="Floater.ToggleOrBringToFront"
+           execute_parameters="grid_status"
+           is_running_function="Floater.IsOpen"
+           is_running_parameters="grid_status"
+           />
 </commands>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 717deba8c7..e96401b511 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -15125,6 +15125,22 @@
         <integer>0</integer>
         </array>
         </map>
+    <key>GridStatusFloaterRect</key>
+    <map>
+        <key>Comment</key>
+        <string>Web profile floater dimensions</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Rect</string>
+        <key>Value</key>
+        <array>
+            <integer>0</integer>
+            <integer>520</integer>
+            <integer>625</integer>
+            <integer>0</integer>
+        </array>
+    </map>
     <key>HelpFloaterOpen</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
new file mode 100644
index 0000000000..a12f717a25
--- /dev/null
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -0,0 +1,84 @@
+/** 
+ * @file llfloatergridstatus.cpp
+ * @brief Grid status floater - uses an embedded web browser to show Grid status info
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatergridstatus.h"
+
+#include "llhttpconstants.h"
+#include "llmediactrl.h"
+#include "llviewercontrol.h"
+
+
+LLFloaterGridStatus::LLFloaterGridStatus(const Params& key) :
+	LLFloaterWebContent(key)
+{
+}
+
+BOOL LLFloaterGridStatus::postBuild()
+{
+	LLFloaterWebContent::postBuild();
+	mWebBrowser->addObserver(this);
+
+	return TRUE;
+}
+
+void LLFloaterGridStatus::onOpen(const LLSD& key)
+{
+	Params p(key);
+	p.trusted_content = true;
+	p.allow_address_entry = false;
+
+	LLFloaterWebContent::onOpen(p);
+	applyPreferredRect();
+	if (mWebBrowser)
+	{
+		std::string url = "http://secondlife-status.statuspage.io/";
+		mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+	}
+}
+// virtual
+void LLFloaterGridStatus::handleReshape(const LLRect& new_rect, bool by_user)
+{
+	if (by_user && !isMinimized())
+	{
+		gSavedSettings.setRect("GridStatusFloaterRect", new_rect);
+	}
+
+	LLFloaterWebContent::handleReshape(new_rect, by_user);
+}
+
+void LLFloaterGridStatus::applyPreferredRect()
+{
+	const LLRect preferred_rect = gSavedSettings.getRect("GridStatusFloaterRect");
+
+	// Don't override position that may have been set by floater stacking code.
+	LLRect new_rect = getRect();
+	new_rect.setLeftTopAndSize(
+		new_rect.mLeft, new_rect.mTop,
+		preferred_rect.getWidth(), preferred_rect.getHeight());
+	setShape(new_rect);
+}
diff --git a/indra/newview/llfloatergridstatus.h b/indra/newview/llfloatergridstatus.h
new file mode 100644
index 0000000000..045c647f4a
--- /dev/null
+++ b/indra/newview/llfloatergridstatus.h
@@ -0,0 +1,56 @@
+/** 
+ * @file llfloatergridstatus.h
+ * @brief Grid status floater - uses an embedded web browser to show Grid status info
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERGRIDSTATUS_H
+#define LL_LLFLOATERGRIDSTATUS_H
+
+#include "llfloaterwebcontent.h"
+#include "llviewermediaobserver.h"
+
+#include <string>
+
+class LLMediaCtrl;
+
+
+class LLFloaterGridStatus :
+	public LLFloaterWebContent
+{
+public:
+	typedef LLSDParamAdapter<_Params> Params;
+
+	LLFloaterGridStatus(const Params& key);
+
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
+
+private:
+	/*virtual*/ BOOL postBuild();
+
+	void applyPreferredRect();
+};
+
+#endif  // LL_LLFLOATERGRIDSTATUS_H
+
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index ec7a81584a..46525e8455 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -70,6 +70,7 @@
 #include "llfloaterfonttest.h"
 #include "llfloatergesture.h"
 #include "llfloatergodtools.h"
+#include "llfloatergridstatus.h"
 #include "llfloatergroups.h"
 #include "llfloaterhelpbrowser.h"
 #include "llfloaterhoverheight.h"
@@ -231,6 +232,7 @@ void LLViewerFloaterReg::registerFloaters()
 
 	LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
 	LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
+	LLFloaterReg::add("grid_status", "floater_grid_status.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGridStatus>);
 	LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>);
 
 	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 760c294f90..bd8c0d5a96 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -136,6 +136,7 @@ with the same filename but different name
   <texture name="Command_Facebook_Icon"     file_name="toolbar_icons/facebook.png"     preload="true" />
   <texture name="Command_Flickr_Icon"       file_name="toolbar_icons/flickr.png"       preload="true" />
   <texture name="Command_Gestures_Icon"     file_name="toolbar_icons/gestures.png"     preload="true" />
+  <texture name="Command_Grid_Status_Icon"  file_name="icons/Info.png" preload="true" />
   <texture name="Command_HowTo_Icon"        file_name="toolbar_icons/howto.png"        preload="true" />
   <texture name="Command_Inventory_Icon"    file_name="toolbar_icons/inventory.png"    preload="true" />
   <texture name="Command_Map_Icon"          file_name="toolbar_icons/map.png"          preload="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_grid_status.xml b/indra/newview/skins/default/xui/en/floater_grid_status.xml
new file mode 100644
index 0000000000..b97bd8056d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_grid_status.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+  positioning="cascading"
+  legacy_header_height="18"
+  can_resize="true"
+  height="775"
+  layout="topleft"
+  min_height="485"
+  min_width="485"
+  name="floater_grid_status"
+  help_topic="floater_grid_status"
+  save_rect="true"
+  save_visibility="true"
+  title=""
+  initial_mime_type="text/html"
+  width="780"
+  tab_stop="true"
+  filename="floater_web_content.xml"/>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index b75f631799..6f00f1731e 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4070,6 +4070,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Facebook_Label">Facebook</string>
   <string name="Command_Flickr_Label">Flickr</string>
   <string name="Command_Gestures_Label">Gestures</string>
+  <string name="Command_Grid_Status_Label">Grid status</string>
   <string name="Command_HowTo_Label">How to</string>
   <string name="Command_Inventory_Label">Inventory</string>
   <string name="Command_Map_Label">Map</string>
@@ -4102,6 +4103,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Facebook_Tooltip">Post to Facebook</string>
   <string name="Command_Flickr_Tooltip">Upload to Flickr</string>
   <string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
+  <string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
   <string name="Command_HowTo_Tooltip">How to do common tasks</string>
   <string name="Command_Inventory_Tooltip">View and use your belongings</string>
   <string name="Command_Map_Tooltip">Map of the world</string>
-- 
cgit v1.2.3


From 85d05c71306489d92212cd5f3e166eff540d8da1 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 13 Feb 2017 11:04:42 +0200
Subject: MAINT-5556 Active listing folder stays listed, with empty Version
 folder

---
 indra/newview/llinventorybridge.cpp | 44 ++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b7f5424f25..6cb7ce622f 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -275,8 +275,10 @@ BOOL LLInvFVBridge::cutToClipboard()
         if (cut_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(mUUID) ||
                                              LLMarketplaceData::instance().isListedAndActive(mUUID)))
         {
-            // Prompt the user if cutting from a marketplace active listing
-            LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInvFVBridge::callback_cutToClipboard, this, _1, _2));
+            LLUUID parent_uuid = obj->getParentUUID();
+            BOOL result = perform_cutToClipboard();
+            gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, parent_uuid);
+            return result;
         }
         else
         {
@@ -303,11 +305,7 @@ BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD
     S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
     if (option == 0) // YES
     {
-		const LLInventoryObject* obj = gInventory.getObject(mUUID);
-		LLUUID parent_uuid = obj->getParentUUID();
-		BOOL result = perform_cutToClipboard();
-		gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, parent_uuid);
-		return result;
+		return perform_cutToClipboard();
     }
     return FALSE;
 }
@@ -3471,7 +3469,24 @@ void LLFolderBridge::pasteFromClipboard()
         const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
         const BOOL paste_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
         
-        if (paste_into_marketplacelistings && !LLMarketplaceData::instance().isListed(mUUID) && LLMarketplaceData::instance().isInActiveFolder(mUUID))
+        BOOL cut_from_marketplacelistings = FALSE;
+        if (LLClipboard::instance().isCutMode())
+        {
+            //Items are not removed from folder on "cut", so we need update listing folder on "paste" operation
+            std::vector<LLUUID> objects;
+            LLClipboard::instance().pasteFromClipboard(objects);
+            for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+            {
+                const LLUUID& item_id = (*iter);
+                if(gInventory.isObjectDescendentOf(item_id, marketplacelistings_id) && (LLMarketplaceData::instance().isInActiveFolder(item_id) ||
+                    LLMarketplaceData::instance().isListedAndActive(item_id)))
+                {
+                    cut_from_marketplacelistings = TRUE;
+                    break;
+                }
+            }
+        }
+        if (cut_from_marketplacelistings || (paste_into_marketplacelistings && !LLMarketplaceData::instance().isListed(mUUID) && LLMarketplaceData::instance().isInActiveFolder(mUUID)))
         {
             // Prompt the user if pasting in a marketplace active version listing (note that pasting right under the listing folder root doesn't need a prompt)
             LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_pasteFromClipboard, this, _1, _2));
@@ -3490,7 +3505,20 @@ void LLFolderBridge::callback_pasteFromClipboard(const LLSD& notification, const
     S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
     if (option == 0) // YES
     {
+        std::vector<LLUUID> objects;
+        std::set<LLUUID> parent_folders;
+        LLClipboard::instance().pasteFromClipboard(objects);
+        for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+        {
+            const LLInventoryObject* obj = gInventory.getObject(*iter);
+            parent_folders.insert(obj->getParentUUID());
+        }
         perform_pasteFromClipboard();
+        for (std::set<LLUUID>::const_iterator iter = parent_folders.begin(); iter != parent_folders.end(); ++iter)
+        {
+            gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, *iter);
+        }
+
     }
 }
 
-- 
cgit v1.2.3


From 1c0a2f87790ca0df8af11f4e5d592723d22d14ea Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 13 Feb 2017 15:50:46 +0200
Subject: MAINT-299 Fixed Inventory not mentioning additional inventory
 shortcut

---
 indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
index 61cc9dfe77..d95541df80 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
@@ -9,6 +9,7 @@
     <menu_item_call
      label="New Inventory Window"
      layout="topleft"
+     shortcut="control|shift|I"
      name="new_window">
         <on_click
          function="Inventory.GearDefault.Custom.Action"
-- 
cgit v1.2.3


From 4524677fe526781e4cb9a987e9504cc3b2edd154 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 13 Feb 2017 20:15:26 +0200
Subject: MAINT-397 Teleport offers are not received after disabling "do not
 disturb" mode

---
 indra/newview/llviewermessage.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d81cb804e4..579eacc315 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3038,16 +3038,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{ 
 				return;
 			}
-			else if (is_do_not_disturb) 
-			{
-				send_do_not_disturb_message(msg, from_id);
-			}
 			else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
 			{
 				return;
 			}
 			else
 			{
+				if (is_do_not_disturb)
+				{
+					send_do_not_disturb_message(msg, from_id);
+				}
+
 				LLVector3 pos, look_at;
 				U64 region_handle(0);
 				U8 region_access(SIM_ACCESS_MIN);
-- 
cgit v1.2.3


From 67edb011b5b803c21652c9735e03a387f26a77d5 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 14 Feb 2017 13:37:45 +0200
Subject: MAINT-7104 Flash toolbar when grid status page is updated

---
 indra/newview/app_settings/commands.xml            |   1 +
 indra/newview/app_settings/settings.xml            |  33 +++++
 indra/newview/llfloatergridstatus.cpp              | 156 +++++++++++++++++----
 indra/newview/llfloatergridstatus.h                |  15 ++
 indra/newview/llstartup.cpp                        |   3 +
 indra/newview/skins/default/textures/textures.xml  |   2 +-
 .../default/textures/toolbar_icons/grid_status.png | Bin 0 -> 483 bytes
 7 files changed, 181 insertions(+), 29 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/toolbar_icons/grid_status.png

diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 64cd11a53a..412d3a53b3 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -294,6 +294,7 @@
            />
   <command name="gridstatus"
            available_in_toybox="true"
+           is_flashing_allowed="true"
            icon="Command_Grid_Status_Icon"
            label_ref="Command_Grid_Status_Label"
            tooltip_ref="Command_Grid_Status_Tooltip"
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e96401b511..fb644d3d5a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5163,6 +5163,39 @@
       <key>Value</key>
       <string>http://wiki.secondlife.com/wiki/[LSL_STRING]</string>
     </map>
+    <key>GridStatusRSS</key>
+    <map>
+      <key>Comment</key>
+      <string>URL that points to SL Grid Status RSS</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>https://secondlife-status.statuspage.io/history.atom</string>
+    </map>
+    <key>GridStatusUpdateDelay</key>
+    <map>
+      <key>Comment</key>
+      <string>Timer delay for updating Grid Status RSS.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>60.0</real>
+    </map>
+    <key>TestGridStatusRSSFromFile</key>
+    <map>
+      <key>Comment</key>
+      <string>For testing only: Don't update rss xml file from server.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LagMeterShrunk</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
index a12f717a25..3429203afe 100644
--- a/indra/newview/llfloatergridstatus.cpp
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -28,57 +28,157 @@
 
 #include "llfloatergridstatus.h"
 
+#include "llcallbacklist.h"
+#include "llcorehttputil.h"
+#include "llfloaterreg.h"
 #include "llhttpconstants.h"
 #include "llmediactrl.h"
+#include "llsdserialize.h"
+#include "lltoolbarview.h"
 #include "llviewercontrol.h"
+#include "llxmltree.h"
 
+std::map<std::string, std::string> LLFloaterGridStatus::sItemsMap;
+const std::string DEFAULT_GRID_STATUS_URL = "http://secondlife-status.statuspage.io/";
 
 LLFloaterGridStatus::LLFloaterGridStatus(const Params& key) :
-	LLFloaterWebContent(key)
+    LLFloaterWebContent(key),
+    mIsFirstUpdate(TRUE)
 {
 }
 
 BOOL LLFloaterGridStatus::postBuild()
 {
-	LLFloaterWebContent::postBuild();
-	mWebBrowser->addObserver(this);
+    LLFloaterWebContent::postBuild();
+    mWebBrowser->addObserver(this);
 
-	return TRUE;
+    return TRUE;
 }
 
 void LLFloaterGridStatus::onOpen(const LLSD& key)
 {
-	Params p(key);
-	p.trusted_content = true;
-	p.allow_address_entry = false;
-
-	LLFloaterWebContent::onOpen(p);
-	applyPreferredRect();
-	if (mWebBrowser)
-	{
-		std::string url = "http://secondlife-status.statuspage.io/";
-		mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
-	}
+    Params p(key);
+    p.trusted_content = true;
+    p.allow_address_entry = false;
+
+    LLFloaterWebContent::onOpen(p);
+    applyPreferredRect();
+    if (mWebBrowser)
+    {
+        mWebBrowser->navigateTo(DEFAULT_GRID_STATUS_URL, HTTP_CONTENT_TEXT_HTML);
+    }
+}
+
+void LLFloaterGridStatus::startGridStatusTimer()
+{
+    checkGridStatusRSS();
+    doPeriodically(boost::bind(&LLFloaterGridStatus::checkGridStatusRSS), gSavedSettings.getF32("GridStatusUpdateDelay"));
+}
+
+bool LLFloaterGridStatus::checkGridStatusRSS()
+{
+    if(gToolBarView->hasCommand(LLCommandId("gridstatus")))
+    {
+        LLCoros::instance().launch("LLFloaterGridStatus::getGridStatusRSSCoro",
+                boost::bind(&LLFloaterGridStatus::getGridStatusRSSCoro));
+    }
+    return false;
+}
+
+void LLFloaterGridStatus::getGridStatusRSSCoro()
+{
+
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+    httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getGridStatusRSSCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+    httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+    std::string url = gSavedSettings.getString("GridStatusRSS");
+
+    LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders);
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status)
+    {
+        return;
+    }
+
+    const LLSD::Binary &rawBody = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
+    std::string body(rawBody.begin(), rawBody.end());
+
+    std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"grid_status_rss.xml");
+    if(!gSavedSettings.getBOOL("TestGridStatusRSSFromFile"))
+    {
+        llofstream custom_file_out(fullpath.c_str(), std::ios::trunc);
+        if (custom_file_out.is_open())
+        {
+            custom_file_out << body;
+            custom_file_out.close();
+        }
+    }
+    LLXmlTree grid_status_xml;
+    if (!grid_status_xml.parseFile(fullpath))
+    {
+        return ;
+    }
+    bool new_entries = false;
+    LLXmlTreeNode* rootp = grid_status_xml.getRoot();
+    for (LLXmlTreeNode* item = rootp->getChildByName( "entry" ); item; item = rootp->getNextNamedChild())
+    {
+        LLXmlTreeNode* id_node = item->getChildByName("id");
+        LLXmlTreeNode* updated_node = item->getChildByName("updated");
+        if (!id_node || !updated_node)
+        {
+            continue;
+        }
+        std::string guid = id_node->getContents();
+        std::string date = updated_node->getContents();
+        if(sItemsMap.find( guid ) == sItemsMap.end())
+        {
+            new_entries = true;
+        }
+        else
+        {
+            if(sItemsMap[guid] != date)
+            {
+                new_entries = true;
+            }
+        }
+        sItemsMap[guid] = date;
+    }
+    if(new_entries && !getInstance()->isFirstUpdate())
+    {
+        gToolBarView->flashCommand(LLCommandId("gridstatus"), true);
+    }
+    getInstance()->setFirstUpdate(FALSE);
 }
+
 // virtual
 void LLFloaterGridStatus::handleReshape(const LLRect& new_rect, bool by_user)
 {
-	if (by_user && !isMinimized())
-	{
-		gSavedSettings.setRect("GridStatusFloaterRect", new_rect);
-	}
+    if (by_user && !isMinimized())
+    {
+        gSavedSettings.setRect("GridStatusFloaterRect", new_rect);
+    }
 
-	LLFloaterWebContent::handleReshape(new_rect, by_user);
+    LLFloaterWebContent::handleReshape(new_rect, by_user);
 }
 
 void LLFloaterGridStatus::applyPreferredRect()
 {
-	const LLRect preferred_rect = gSavedSettings.getRect("GridStatusFloaterRect");
-
-	// Don't override position that may have been set by floater stacking code.
-	LLRect new_rect = getRect();
-	new_rect.setLeftTopAndSize(
-		new_rect.mLeft, new_rect.mTop,
-		preferred_rect.getWidth(), preferred_rect.getHeight());
-	setShape(new_rect);
+    const LLRect preferred_rect = gSavedSettings.getRect("GridStatusFloaterRect");
+
+    LLRect new_rect = getRect();
+    new_rect.setLeftTopAndSize(
+        new_rect.mLeft, new_rect.mTop,
+        preferred_rect.getWidth(), preferred_rect.getHeight());
+    setShape(new_rect);
+}
+
+LLFloaterGridStatus* LLFloaterGridStatus::getInstance()
+{
+    return LLFloaterReg::getTypedInstance<LLFloaterGridStatus>("grid_status");
 }
diff --git a/indra/newview/llfloatergridstatus.h b/indra/newview/llfloatergridstatus.h
index 045c647f4a..1608515003 100644
--- a/indra/newview/llfloatergridstatus.h
+++ b/indra/newview/llfloatergridstatus.h
@@ -46,10 +46,25 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
 
+	static bool checkGridStatusRSS();
+	static void getGridStatusRSSCoro();
+
+	void startGridStatusTimer();
+	BOOL isFirstUpdate() { return mIsFirstUpdate; }
+	void setFirstUpdate(BOOL first_update) { mIsFirstUpdate = first_update; }
+
+	static LLFloaterGridStatus* getInstance();
+
+
 private:
 	/*virtual*/ BOOL postBuild();
 
 	void applyPreferredRect();
+
+	static std::map<std::string, std::string> sItemsMap;
+
+    LLFrameTimer    mGridStatusTimer;
+    BOOL            mIsFirstUpdate;
 };
 
 #endif  // LL_LLFLOATERGRIDSTATUS_H
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index b762b2ae1c..347409fcab 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -56,6 +56,7 @@
 #include "llerrorcontrol.h"
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
+#include "llfloatergridstatus.h"
 #include "llfloaterimsession.h"
 #include "lllocationhistory.h"
 #include "llimageworker.h"
@@ -1875,6 +1876,8 @@ bool idle_startup()
 
 		LLFloaterReg::showInitialVisibleInstances();
 
+		LLFloaterGridStatus::getInstance()->startGridStatusTimer();
+
 		display_startup();
 
 		display_startup();
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index bd8c0d5a96..d757e39366 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -136,7 +136,7 @@ with the same filename but different name
   <texture name="Command_Facebook_Icon"     file_name="toolbar_icons/facebook.png"     preload="true" />
   <texture name="Command_Flickr_Icon"       file_name="toolbar_icons/flickr.png"       preload="true" />
   <texture name="Command_Gestures_Icon"     file_name="toolbar_icons/gestures.png"     preload="true" />
-  <texture name="Command_Grid_Status_Icon"  file_name="icons/Info.png" preload="true" />
+  <texture name="Command_Grid_Status_Icon"  file_name="toolbar_icons/grid_status.png"  preload="true" />
   <texture name="Command_HowTo_Icon"        file_name="toolbar_icons/howto.png"        preload="true" />
   <texture name="Command_Inventory_Icon"    file_name="toolbar_icons/inventory.png"    preload="true" />
   <texture name="Command_Map_Icon"          file_name="toolbar_icons/map.png"          preload="true" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/grid_status.png b/indra/newview/skins/default/textures/toolbar_icons/grid_status.png
new file mode 100644
index 0000000000..b92b93cfb4
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/grid_status.png differ
-- 
cgit v1.2.3


From 6e06281477840e2403d52510b54bf2cd99dd8216 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 14 Feb 2017 15:46:27 +0200
Subject: MAINT-7104 whitespace clean-up

---
 indra/newview/llfloatergridstatus.cpp |  2 +-
 indra/newview/llfloatergridstatus.h   | 30 +++++++++++++++---------------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
index 3429203afe..c47ff1c1d9 100644
--- a/indra/newview/llfloatergridstatus.cpp
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -4,7 +4,7 @@
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2017, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/indra/newview/llfloatergridstatus.h b/indra/newview/llfloatergridstatus.h
index 1608515003..0c3deb7d4c 100644
--- a/indra/newview/llfloatergridstatus.h
+++ b/indra/newview/llfloatergridstatus.h
@@ -4,7 +4,7 @@
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2017, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,32 +36,32 @@ class LLMediaCtrl;
 
 
 class LLFloaterGridStatus :
-	public LLFloaterWebContent
+    public LLFloaterWebContent
 {
 public:
-	typedef LLSDParamAdapter<_Params> Params;
+    typedef LLSDParamAdapter<_Params> Params;
 
-	LLFloaterGridStatus(const Params& key);
+    LLFloaterGridStatus(const Params& key);
 
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
+    /*virtual*/ void onOpen(const LLSD& key);
+    /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
 
-	static bool checkGridStatusRSS();
-	static void getGridStatusRSSCoro();
+    static bool checkGridStatusRSS();
+    static void getGridStatusRSSCoro();
 
-	void startGridStatusTimer();
-	BOOL isFirstUpdate() { return mIsFirstUpdate; }
-	void setFirstUpdate(BOOL first_update) { mIsFirstUpdate = first_update; }
+    void startGridStatusTimer();
+    BOOL isFirstUpdate() { return mIsFirstUpdate; }
+    void setFirstUpdate(BOOL first_update) { mIsFirstUpdate = first_update; }
 
-	static LLFloaterGridStatus* getInstance();
+    static LLFloaterGridStatus* getInstance();
 
 
 private:
-	/*virtual*/ BOOL postBuild();
+    /*virtual*/ BOOL postBuild();
 
-	void applyPreferredRect();
+    void applyPreferredRect();
 
-	static std::map<std::string, std::string> sItemsMap;
+    static std::map<std::string, std::string> sItemsMap;
 
     LLFrameTimer    mGridStatusTimer;
     BOOL            mIsFirstUpdate;
-- 
cgit v1.2.3


From 3c249e5d5fca71714d7686c19d093962fbec313e Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 15 Feb 2017 14:52:33 +0200
Subject: MAINT-7051 Release Notes url shouldn't include the EDU parameter

---
 indra/newview/llappviewer.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 5eb82a2d0b..62e32c0bdc 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3312,7 +3312,12 @@ LLSD LLAppViewer::getViewerInfo() const
 	std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
 	if (! LLStringUtil::endsWith(url, "/"))
 		url += "/";
-	url += LLURI::escape(LLVersionInfo::getChannel()) + "/";
+	std::string channel = LLVersionInfo::getChannel();
+	if (LLStringUtil::endsWith(boost::to_lower_copy(channel), " edu")) // Release Notes url shouldn't include the EDU parameter
+	{
+		boost::erase_tail(channel, 4);
+	}
+	url += LLURI::escape(channel) + "/";
 	url += LLURI::escape(LLVersionInfo::getVersion());
 
 	info["VIEWER_RELEASE_NOTES_URL"] = url;
-- 
cgit v1.2.3


From 515a2f9c39506e22595aacee3c397daca58c9c15 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 16 Feb 2017 14:46:10 +0200
Subject: MAINT-7132 snapshot window should re-open in last selected mode

---
 indra/newview/llfloatersnapshot.cpp    | 4 ----
 indra/newview/llpanelsnapshotlocal.cpp | 3 +--
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index c0980719bb..ba3106913c 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -653,10 +653,6 @@ void LLFloaterSnapshot::Impl::setFinished(bool finished, bool ok, const std::str
 		LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
 		std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
 		finished_lbl->setValue(result_text);
-
-		LLSideTrayPanelContainer* panel_container = mFloater->getChild<LLSideTrayPanelContainer>("panel_container");
-		panel_container->openPreviousPanel();
-		panel_container->getCurrentPanel()->onOpen(LLSD());
 	}
 }
 
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index 3652c10586..51ec964ace 100644
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -168,12 +168,11 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
 	if (saved)
 	{
 		mSnapshotFloater->postSave();
-		goBack();
 		floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
 	}
 	else
 	{
-		cancel();
+		floater->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
 	}
 }
 
-- 
cgit v1.2.3


From 58cb66135257487ccbca693215f8c1d72576deeb Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 17 Feb 2017 15:19:57 +0200
Subject: MAINT-397 Fixing confusing behavior

---
 indra/newview/skins/default/xui/en/notifications.xml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c4190a4940..a509adfcbc 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4326,7 +4326,6 @@ Cannot offer friendship at this time. Please try again in a moment.
 Do Not Disturb is on.  You will not be notified of incoming communications.
 
 - Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
-- Teleportation offers will be declined.
 - Voice calls will be rejected.
     <usetemplate
      ignoretext="I change my status to Do Not Disturb mode"
-- 
cgit v1.2.3


From 094c13d63b1fb210c6fc702600b89e695169a24d Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 20 Feb 2017 11:20:03 +0200
Subject: MAINT-7142 Use '/completename' in teleport offer and eject messages

---
 indra/newview/llpanelgrouproles.cpp | 2 +-
 indra/newview/llviewermessage.cpp   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 00c204e702..6ac439177a 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1231,7 +1231,7 @@ void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, c
 		for (uuid_vec_t::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i)
 		{
 			LLSD args;
-			args["AVATAR_NAME"] = LLSLURL("agent", *i, "displayname").getSLURLString();
+			args["AVATAR_NAME"] = LLSLURL("agent", *i, "completename").getSLURLString();
 			args["GROUP_NAME"] = group_data->mName;
 			
 			LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 579eacc315..8076c6b1df 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -7034,7 +7034,7 @@ void send_lures(const LLSD& notification, const LLSD& response)
 			std::string target_name;
 			gCacheName->getFullName(target_id, target_name);  // for im log filenames
 			LLSD args;
-			args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
+			args["TO_NAME"] = LLSLURL("agent", target_id, "completename").getSLURLString();;
 	
 			LLSD payload;
 				
-- 
cgit v1.2.3


From da3fde24aa6fe06077dafeff6c7cafacaa50674a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 20 Feb 2017 11:24:30 +0200
Subject: MAINT-7133 add object name to inventory offer chat message

---
 indra/newview/llgiveinventory.cpp              | 23 ++++++++++++++---------
 indra/newview/llgiveinventory.h                |  4 +++-
 indra/newview/skins/default/xui/en/strings.xml |  5 ++++-
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index a9bf8a9a50..b2271cf4ff 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -306,21 +306,23 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
 //////////////////////////////////////////////////////////////////////////
 
 //static
-void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id)
+void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id, const std::string& item_name, bool is_folder)
 {
 	// compute id of possible IM session with agent that has "to_agent" id
 	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, to_agent);
 	// If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat.
 	LLSD args;
 	args["user_id"] = to_agent;
+	args["ITEM_NAME"] = item_name;
+	std::string message_name = is_folder ? "inventory_folder_offered" : "inventory_item_offered";
 	if (im_session_id.notNull())
 	{
-		gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);
+		gIMMgr->addSystemMessage(im_session_id, message_name, args);
 	}
 	// If this item was given by drag-and-drop on avatar while IM panel was open, log this action in the IM panel chat.
 	else if (LLIMModel::getInstance()->findIMSession(session_id))
 	{
-		gIMMgr->addSystemMessage(session_id, "inventory_item_offered", args);
+		gIMMgr->addSystemMessage(session_id, message_name, args);
 	}
 	// If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history.
 	else
@@ -331,7 +333,9 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im
 			// Build a new format username or firstname_lastname for legacy names
 			// to use it for a history log filename.
 			full_name = LLCacheName::buildUsername(full_name);
-			LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, LLTrans::getString("inventory_item_offered-im"));
+			LLUIString message = LLTrans::getString(message_name + "-im");
+			message.setArgs(args);
+			LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, message.getString());
 		}
 	}
 }
@@ -385,6 +389,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 {
 	if (!item) return;
 	std::string name;
+	std::string item_name = item->getName();
 	LLAgentUI::buildFullname(name);
 	LLUUID transaction_id;
 	transaction_id.generate();
@@ -399,7 +404,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 		gAgentSessionID,
 		to_agent,
 		name,
-		item->getName(),
+		item_name,
 		IM_ONLINE,
 		IM_INVENTORY_OFFERED,
 		transaction_id,
@@ -421,7 +426,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 
 	LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
 
-	logInventoryOffer(to_agent, im_session_id);
+	logInventoryOffer(to_agent, im_session_id, item_name);
 
 	// add buddy to recent people list
 	LLRecentPeople::instance().add(to_agent);
@@ -501,7 +506,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 		items,
 		LLInventoryModel::EXCLUDE_TRASH,
 		giveable);
-
+	std::string cat_name = cat->getName();
 	bool give_successful = true;
 	// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
 	// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
@@ -556,7 +561,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 			gAgent.getSessionID(),
 			to_agent,
 			name,
-			cat->getName(),
+			cat_name,
 			IM_ONLINE,
 			IM_INVENTORY_OFFERED,
 			transaction_id,
@@ -579,7 +584,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 
 		LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
 
-		logInventoryOffer(to_agent, im_session_id);
+		logInventoryOffer(to_agent, im_session_id, cat_name, true);
 	}
 
 	return give_successful;
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index 85bc1ed49c..20e6df76e5 100644
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -78,7 +78,9 @@ private:
 	 * logs "Inventory item offered" to IM
 	 */
 	static void logInventoryOffer(const LLUUID& to_agent,
-									const LLUUID &im_session_id = LLUUID::null);
+									const LLUUID &im_session_id = LLUUID::null,
+									const std::string& item_name = std::string(),
+									bool is_folder = false);
 
 	static void commitGiveInventoryItem(const LLUUID& to_agent,
 									const LLInventoryItem* item,
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 6f00f1731e..aad2c611f4 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3628,7 +3628,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
     Conference with [AGENT_NAME]
   </string>
   <string name="inventory_item_offered-im">
-    Inventory item offered
+    Inventory item '[ITEM_NAME]' offered
+  </string>
+  <string name="inventory_folder_offered-im">
+    Inventory folder '[ITEM_NAME]' offered
   </string>
   <string name="share_alert">
     Drag items from inventory here
-- 
cgit v1.2.3


From a6b3bb1a2d7c0bac90918f75b67a8066d95a4783 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 20 Feb 2017 14:20:43 +0200
Subject: MAINT-7146 No callback for 'Url.RemoveFriend' in LLScrollListCtrl

---
 indra/llui/llscrolllistctrl.cpp | 7 +++++++
 indra/llui/llscrolllistctrl.h   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index db8fdc46b7..0afa8d43f1 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1808,6 +1808,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 			registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group));
 			registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
 			registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
+			registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
 			registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
 			registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
 			registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1852,6 +1853,12 @@ void LLScrollListCtrl::addFriend(std::string id)
 	LLUrlAction::addFriend(slurl);
 }
 
+void LLScrollListCtrl::removeFriend(std::string id)
+{
+	std::string slurl = "secondlife:///app/agent/" + id + "/about";
+	LLUrlAction::removeFriend(slurl);
+}
+
 void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
 {
 	// open the resident's details or the group details
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 6325a79cd5..8343750a54 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -432,6 +432,7 @@ private:
 	static void		showProfile(std::string id, bool is_group);
 	static void		sendIM(std::string id);
 	static void		addFriend(std::string id);
+	static void		removeFriend(std::string id);
 	static void		showNameDetails(std::string id, bool is_group);
 	static void		copyNameToClipboard(std::string id, bool is_group);
 	static void		copySLURLToClipboard(std::string id, bool is_group);
-- 
cgit v1.2.3


From 3faad84a533b80e4a40e29e880d1608ffb0763ef Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 21 Feb 2017 18:01:23 +0200
Subject: MAINT-7036 Communicate Menu - Voice Morphing - Subscribe Now options
 - update

---
 indra/newview/llviewermenu.cpp                     | 9 ++++++++-
 indra/newview/skins/default/xui/en/menu_viewer.xml | 6 ++++++
 indra/newview/skins/default/xui/en/strings.xml     | 3 ++-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 99b7a98abc..d847661ce7 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8618,7 +8618,12 @@ public:
 
 void handle_voice_morphing_subscribe()
 {
-	LLWeb::loadURLExternal(LLTrans::getString("voice_morphing_url"));
+	LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
+}
+
+void handle_premium_voice_morphing_subscribe()
+{
+	LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url"));
 }
 
 class LLToggleUIHints : public view_listener_t
@@ -8814,6 +8819,8 @@ void initialize_menus()
 
 	// Communicate > Voice morphing > Subscribe...
 	commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
+	// Communicate > Voice morphing > Premium perk...
+	commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe));
 	LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
 	enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
 		, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 332d79e1ea..c96b7ae673 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -337,6 +337,12 @@
                 <menu_item_call.on_click
                  function="Communicate.VoiceMorphing.Subscribe" />
             </menu_item_call>
+            <menu_item_call
+             label="Premium perk..."
+             name="PremiumPerk">
+                <menu_item_call.on_click
+                 function="Communicate.VoiceMorphing.PremiumPerk" />
+            </menu_item_call>
         </menu>
         <menu_item_check
          label="Gestures..."
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index aad2c611f4..1d2c068e64 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3739,7 +3739,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 
   <string name="Home position set.">Home position set.</string>
 
-  <string name="voice_morphing_url">http://secondlife.com/landing/voicemorphing</string>
+  <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string>
+  <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string>
 
   <!-- Financial operations strings -->
   <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string>
-- 
cgit v1.2.3


From aa52236c5570a0b971b2524da655ccff6a1bff0d Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 21 Feb 2017 19:30:41 +0200
Subject: MAINT-768 Fixed mouse hover triggers foreground and background UI

---
 indra/newview/llinventorylistitem.cpp | 4 ++--
 indra/newview/llinventorylistitem.h   | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 0601796436..12bb609df8 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -182,10 +182,10 @@ void LLPanelInventoryListItemBase::setValue(const LLSD& value)
 	mSelected = value["selected"];
 }
 
-void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
+BOOL LLPanelInventoryListItemBase::handleHover(S32 x, S32 y, MASK mask)
 {
 	mHovered = true;
-	LLPanel::onMouseEnter(x, y, mask);
+	return LLPanel::handleHover(x, y, mask);
 }
 
 void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h
index b1ef6c74ee..d4dd212cc3 100644
--- a/indra/newview/llinventorylistitem.h
+++ b/indra/newview/llinventorylistitem.h
@@ -129,8 +129,8 @@ public:
 	 */
 	/*virtual*/ S32  notify(const LLSD& info);
 
-	 /* Highlights item */
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+	/* Highlights item */
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 	/* Removes item highlight */
 	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
 
@@ -153,6 +153,7 @@ public:
 	LLViewerInventoryItem* getItem() const;
 
 	void setSeparatorVisible(bool visible) { mSeparatorVisible = visible; }
+	void resetHighlight() { mHovered = FALSE; }
 
 	virtual ~LLPanelInventoryListItemBase(){}
 
-- 
cgit v1.2.3


From 9c015df3fab0b5cc229ad1a0393e5da50ee29883 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 21 Feb 2017 15:50:09 +0200
Subject: MAINT-389 Fixed No way to wear an outfit from Library besides
 drag-n-drop

---
 indra/newview/llinventorybridge.cpp | 96 +++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 25 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 6cb7ce622f..555c19baac 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3941,6 +3941,37 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 			mWearables=TRUE;
 		}
 	}
+	else
+	{
+		// Mark wearables and allow copy from library
+		LLInventoryModel* model = getInventoryModel();
+		if(!model) return;
+		const LLInventoryCategory* category = model->getCategory(mUUID);
+		if (!category) return;
+		LLFolderType::EType type = category->getPreferredType();
+		const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
+
+		LLFindWearables is_wearable;
+		LLIsType is_object(LLAssetType::AT_OBJECT);
+		LLIsType is_gesture(LLAssetType::AT_GESTURE);
+
+		if (checkFolderForContentsOfType(model, is_wearable) ||
+			checkFolderForContentsOfType(model, is_object) ||
+			checkFolderForContentsOfType(model, is_gesture))
+		{
+			mWearables = TRUE;
+		}
+
+		if (!is_system_folder)
+		{
+			items.push_back(std::string("Copy"));
+			if (!isItemCopyable())
+			{
+				// For some reason there are items in library that can't be copied directly
+				disabled_items.push_back(std::string("Copy"));
+			}
+		}
+	}
 
 	// Preemptively disable system folder removal if more than one item selected.
 	if ((flags & FIRST_SELECTED_ITEM) == 0)
@@ -3948,7 +3979,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 		disabled_items.push_back(std::string("Delete System Folder"));
 	}
 
-	if (!isMarketplaceListingsFolder())
+	if (isAgentInventory() && !isMarketplaceListingsFolder())
 	{
 		items.push_back(std::string("Share"));
 		if (!canShare())
@@ -3956,6 +3987,9 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 			disabled_items.push_back(std::string("Share"));
 		}
 	}
+
+	
+
 	// Add menu items that are dependent on the contents of the folder.
 	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
 	if (category && (marketplace_listings_id != mUUID))
@@ -3993,7 +4027,6 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 	if (trash_id == mUUID) return;
 	if (isItemInTrash()) return;
-	if (!isAgentInventory()) return;
     
 	if (!isItemRemovable())
 	{
@@ -4006,9 +4039,10 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	// BAP change once we're no longer treating regular categories as ensembles.
 	const bool is_ensemble = (type == LLFolderType::FT_NONE ||
 		LLFolderType::lookupIsEnsembleType(type));
+	const bool is_agent_inventory = isAgentInventory();
 
 	// Only enable calling-card related options for non-system folders.
-	if (!is_system_folder)
+	if (!is_system_folder && is_agent_inventory)
 	{
 		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
 		if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
@@ -4020,7 +4054,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	}
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
-	if (LLFolderType::lookupIsProtectedType(type))
+	if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
 	{
 		items.push_back(std::string("Delete System Folder"));
 	}
@@ -4037,8 +4071,6 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 		checkFolderForContentsOfType(model, is_object) ||
 		checkFolderForContentsOfType(model, is_gesture) )
 	{
-		items.push_back(std::string("Folder Wearables Separator"));
-
 		// Only enable add/replace outfit for non-system folders.
 		if (!is_system_folder)
 		{
@@ -4049,25 +4081,30 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 			}
 
 			items.push_back(std::string("Replace Outfit"));
+
+			if (is_agent_inventory)
+			{
+				items.push_back(std::string("Folder Wearables Separator"));
+				if (is_ensemble)
+				{
+					items.push_back(std::string("Wear As Ensemble"));
+				}
+				items.push_back(std::string("Remove From Outfit"));
+				if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
+				{
+					disabled_items.push_back(std::string("Remove From Outfit"));
+				}
+			}
+			if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
+			{
+				disabled_items.push_back(std::string("Replace Outfit"));
+			}
+			if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
+			{
+				disabled_items.push_back(std::string("Add To Outfit"));
+			}
+			items.push_back(std::string("Outfit Separator"));
 		}
-		if (is_ensemble)
-		{
-			items.push_back(std::string("Wear As Ensemble"));
-		}
-		items.push_back(std::string("Remove From Outfit"));
-		if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
-		{
-			disabled_items.push_back(std::string("Remove From Outfit"));
-		}
-		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
-		{
-			disabled_items.push_back(std::string("Replace Outfit"));
-		}
-		if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
-		{
-			disabled_items.push_back(std::string("Add To Outfit"));
-		}
-		items.push_back(std::string("Outfit Separator"));
 	}
 }
 
@@ -4304,9 +4341,18 @@ void LLFolderBridge::modifyOutfit(BOOL append)
 		return;
 	}
 
-	LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append );
+	if (isAgentInventory())
+	{
+		LLAppearanceMgr::instance().wearInventoryCategory(cat, FALSE, append);
+	}
+	else
+	{
+		// Library, we need to copy content first
+		LLAppearanceMgr::instance().wearInventoryCategory(cat, TRUE, append);
+	}
 }
 
+
 // +=================================================+
 // |        LLMarketplaceFolderBridge                |
 // +=================================================+
-- 
cgit v1.2.3


From 605160d501158362ced3e62425bdcd8d28895fd5 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 15 Feb 2017 20:40:03 +0200
Subject: MAINT-7118 Swapping legacy people API with new cache

---
 indra/llmessage/llavatarnamecache.cpp          | 22 ++++++++
 indra/llmessage/llavatarnamecache.h            | 10 +++-
 indra/newview/llavataractions.cpp              | 41 +++++++-------
 indra/newview/llcallingcard.cpp                | 12 +++--
 indra/newview/llchathistory.cpp                |  6 +--
 indra/newview/llconversationmodel.cpp          |  8 +--
 indra/newview/llfloaterconversationpreview.cpp |  3 +-
 indra/newview/llfloaterimcontainer.cpp         |  7 +--
 indra/newview/llfloaterimnearbychat.cpp        |  2 +-
 indra/newview/llfloaterproperties.cpp          | 11 ++--
 indra/newview/llfloaterscriptlimits.cpp        | 27 ++++++++--
 indra/newview/llfloaterscriptlimits.h          |  3 ++
 indra/newview/llgiveinventory.cpp              |  7 +--
 indra/newview/llgroupmgr.cpp                   |  8 +--
 indra/newview/llimview.cpp                     | 20 +++----
 indra/newview/llimview.h                       |  2 +-
 indra/newview/llinventorymodel.cpp             | 11 ++--
 indra/newview/llmutelist.cpp                   | 27 +++++-----
 indra/newview/llnamebox.cpp                    |  5 +-
 indra/newview/llnameeditor.cpp                 |  5 +-
 indra/newview/llnotificationhandlerutil.cpp    | 28 +++++++---
 indra/newview/llpanelgrouproles.cpp            | 12 ++---
 indra/newview/llpanelpicks.cpp                 |  6 +--
 indra/newview/llselectmgr.cpp                  |  7 +--
 indra/newview/llspeakers.cpp                   |  7 +--
 indra/newview/llspeakers.h                     |  3 +-
 indra/newview/lltooldraganddrop.cpp            | 12 ++---
 indra/newview/lltoolpie.cpp                    | 23 ++++----
 indra/newview/llviewerinventory.cpp            | 10 ++--
 indra/newview/llviewerinventory.h              |  3 +-
 indra/newview/llviewermenu.cpp                 |  6 +--
 indra/newview/llviewermessage.cpp              | 74 +++++++++++++++++++-------
 32 files changed, 280 insertions(+), 148 deletions(-)

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 004db546b7..5a112b5432 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -755,6 +755,28 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
 	sCache[agent_id] = av_name;
 }
 
+LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
+{
+    std::map<LLUUID, LLAvatarName>::iterator it;
+    std::map<LLUUID, LLAvatarName>::iterator end = sCache.end();
+    for (it = sCache.begin(); it != end; ++it)
+    {
+        if (it->second.getUserName() == name)
+        {
+            return it->first;
+        }
+    }
+
+    // Legacy method
+    LLUUID id;
+    if (gCacheName->getUUID(name, id))
+    {
+        return id;
+    }
+
+    return LLUUID::null;
+}
+
 #if 0
 F64 LLAvatarNameCache::nameExpirationFromHeaders(LLCore::HttpHeaders *headers)
 {
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index bd2715e956..63e067c939 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -84,7 +84,15 @@ namespace LLAvatarNameCache
 	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
 	void erase(const LLUUID& agent_id);
 
-    /// Provide some fallback for agents that return errors.
+	// A way to find agent id by UUID, very slow, also unreliable
+	// since it doesn't request names, just serch exsisting ones
+	// that are likely not in cache.
+	//
+	// Todo: Find a way to remove this.
+	// Curently this method is used for chat history and in some cases notices.
+	LLUUID findIdByName(const std::string& name);
+
+	/// Provide some fallback for agents that return errors.
 	void handleAgentError(const LLUUID& agent_id);
 
 	// Compute name expiration time from HTTP Cache-Control header,
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 36e95c07f4..2045c3e297 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -478,15 +478,14 @@ void LLAvatarActions::kick(const LLUUID& id)
 // static
 void LLAvatarActions::freezeAvatar(const LLUUID& id)
 {
-	std::string fullname;
-	gCacheName->getFullName(id, fullname);
+	LLAvatarName av_name;
 	LLSD payload;
 	payload["avatar_id"] = id;
 
-	if (!fullname.empty())
+	if (LLAvatarNameCache::get(id, &av_name))
 	{
 		LLSD args;
-		args["AVATAR_NAME"] = fullname;
+		args["AVATAR_NAME"] = av_name.getUserName();
 		LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, handleFreezeAvatar);
 	}
 	else
@@ -498,15 +497,15 @@ void LLAvatarActions::freezeAvatar(const LLUUID& id)
 // static
 void LLAvatarActions::ejectAvatar(const LLUUID& id, bool ban_enabled)
 {
-	std::string fullname;
-	gCacheName->getFullName(id, fullname);
+	LLAvatarName av_name;
 	LLSD payload;
 	payload["avatar_id"] = id;
 	payload["ban_enabled"] = ban_enabled;
 	LLSD args;
-	if (!fullname.empty())
+	bool has_name = LLAvatarNameCache::get(id, &av_name);
+	if (has_name)
 	{
-		args["AVATAR_NAME"] = fullname;
+		args["AVATAR_NAME"] = av_name.getUserName();
 	}
 
 	if (ban_enabled)
@@ -515,7 +514,7 @@ void LLAvatarActions::ejectAvatar(const LLUUID& id, bool ban_enabled)
 	}
 	else
 	{
-		if (!fullname.empty())
+		if (has_name)
 		{
 			LLNotificationsUtil::add("EjectAvatarFullnameNoBan", args, payload, handleEjectAvatar);
 		}
@@ -991,10 +990,10 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 // static
 void LLAvatarActions::toggleBlock(const LLUUID& id)
 {
-	std::string name;
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
 
-	gCacheName->getFullName(id, name); // needed for mute
-	LLMute mute(id, name, LLMute::AGENT);
+	LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 
 	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
 	{
@@ -1009,13 +1008,13 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
 // static
 void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
 {
-	std::string name;
-	gCacheName->getFullName(id, name); // needed for mute
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
 
 	LLMuteList* mute_list = LLMuteList::getInstance();
 	bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
 
-	LLMute mute(id, name, LLMute::AGENT);
+	LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 	if (!is_muted)
 	{
 		mute_list->add(mute, LLMute::flagVoiceChat);
@@ -1329,9 +1328,9 @@ bool LLAvatarActions::isFriend(const LLUUID& id)
 // static
 bool LLAvatarActions::isBlocked(const LLUUID& id)
 {
-	std::string name;
-	gCacheName->getFullName(id, name); // needed for mute
-	return LLMuteList::getInstance()->isMuted(id, name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
+	return LLMuteList::getInstance()->isMuted(id, av_name.getUserName());
 }
 
 // static
@@ -1343,8 +1342,10 @@ bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
 // static
 bool LLAvatarActions::canBlock(const LLUUID& id)
 {
-	std::string full_name;
-	gCacheName->getFullName(id, full_name); // needed for mute
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
+
+	std::string full_name = av_name.getUserName();
 	bool is_linden = (full_name.find("Linden") != std::string::npos);
 	bool is_self = id == gAgentID;
 	return !is_self && !is_linden;
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index f79d1aa609..6d20b23e9f 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -243,7 +243,6 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
 	using namespace std;
 
 	U32 new_buddy_count = 0;
-	std::string full_name;
 	LLUUID agent_id;
 	for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr)
 	{
@@ -253,8 +252,11 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
 		{
 			++new_buddy_count;
 			mBuddyInfo[agent_id] = (*itr).second;
-			// IDEVO: is this necessary?  name is unused?
-			gCacheName->getFullName(agent_id, full_name);
+
+			// pre-request name for notifications?
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(agent_id, &av_name);
+
 			addChangedMask(LLFriendObserver::ADD, agent_id);
 			LL_DEBUGS() << "Added buddy " << agent_id
 					<< ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline")
@@ -889,7 +891,9 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship
 
 bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
 {
-	gCacheName->getFullName(buddy_id, mFullName);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(buddy_id, &av_name);
+	mFullName = av_name.getUserName();
 	buddy_map_t::value_type value(buddy_id, mFullName);
 	if(buddy->isOnline())
 	{
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 5d2997688f..9798ef3529 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -271,9 +271,9 @@ public:
 	void mute(const LLUUID& participant_id, U32 flags)
 	{
 		BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
-		std::string name;
-		gCacheName->getFullName(participant_id, name);
-		LLMute mute(participant_id, name, LLMute::AGENT);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(participant_id, &av_name);
+		LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT);
 
 		if (!is_muted)
 		{
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 328a638f2f..ebbbf23dee 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -602,12 +602,12 @@ bool LLConversationItemParticipant::isVoiceMuted()
 
 void LLConversationItemParticipant::muteVoice(bool mute_voice)
 {
-	std::string name;
-	gCacheName->getFullName(mUUID, name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(mUUID, &av_name);
 	LLMuteList * mute_listp = LLMuteList::getInstance();
-	bool voice_already_muted = mute_listp->isMuted(mUUID, name);
+	bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName());
 
-	LLMute mute(mUUID, name, LLMute::AGENT);
+	LLMute mute(mUUID, av_name.getUserName(), LLMute::AGENT);
 	if (voice_already_muted && !mute_voice)
 	{
 		mute_listp->remove(mute);
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index a358b7c10b..b48ecc8f31 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -25,6 +25,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llavatarnamecache.h"
 #include "llconversationlog.h"
 #include "llfloaterconversationpreview.h"
 #include "llimview.h"
@@ -220,7 +221,7 @@ void LLFloaterConversationPreview::showHistory()
 		else
  		{
 			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
+			from_id = LLAvatarNameCache::findIdByName(legacy_name);
  		}
 
 		LLChat chat;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 7007c58b3c..3522932d03 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -2099,9 +2099,10 @@ void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
 void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags)
 {
         BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
-        std::string name;
-        gCacheName->getFullName(participant_id, name);
-        LLMute mute(participant_id, name, LLMute::AGENT);
+
+        LLAvatarName av_name;
+        LLAvatarNameCache::get(participant_id, &av_name);
+        LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT);
 
         if (!is_muted)
         {
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 7d0ff22ed3..40ae22bb4e 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -218,7 +218,7 @@ void LLFloaterIMNearbyChat::loadHistory()
 		else
  		{
 			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
+			from_id = LLAvatarNameCache::findIdByName(legacy_name);
  		}
 
 		LLChat chat;
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index 6bfc780722..1310a60638 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -30,6 +30,7 @@
 #include <algorithm>
 #include <functional>
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 #include "lldbstrings.h"
 #include "llfloaterreg.h"
 
@@ -274,12 +275,12 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
 
 	if (item->getCreatorUUID().notNull())
 	{
-		std::string name;
-		gCacheName->getFullName(item->getCreatorUUID(), name);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(item->getCreatorUUID(), &av_name);
 		getChildView("BtnCreator")->setEnabled(TRUE);
 		getChildView("LabelCreatorTitle")->setEnabled(TRUE);
 		getChildView("LabelCreatorName")->setEnabled(TRUE);
-		getChild<LLUICtrl>("LabelCreatorName")->setValue(name);
+		getChild<LLUICtrl>("LabelCreatorName")->setValue(av_name.getUserName());
 	}
 	else
 	{
@@ -301,7 +302,9 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
 		}
 		else
 		{
-			gCacheName->getFullName(perm.getOwner(), name);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(perm.getOwner(), &av_name);
+			name = av_name.getUserName();
 		}
 		getChildView("BtnOwner")->setEnabled(TRUE);
 		getChildView("LabelOwnerTitle")->setEnabled(TRUE);
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index c14bb4e7ae..5f0587a286 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -390,6 +390,14 @@ void LLPanelScriptLimitsRegionMemory::setErrorStatus(S32 status, const std::stri
 	LL_WARNS() << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<LL_ENDL;
 }
 
+// callback from the name cache with an owner name to add to the list
+void LLPanelScriptLimitsRegionMemory::onAvatarNameCache(
+    const LLUUID& id,
+    const LLAvatarName& av_name)
+{
+    onNameCache(id, av_name.getUserName());
+}
+
 // callback from the name cache with an owner name to add to the list
 void LLPanelScriptLimitsRegionMemory::onNameCache(
 						 const LLUUID& id,
@@ -503,7 +511,9 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
 				}
 				else
 				{
-					name_is_cached = gCacheName->getFullName(owner_id, owner_buf);  // username
+					LLAvatarName av_name;
+					name_is_cached = LLAvatarNameCache::get(owner_id, &av_name);
+					owner_buf = av_name.getUserName();
 					owner_buf = LLCacheName::buildUsername(owner_buf);
 				}
 				if(!name_is_cached)
@@ -511,9 +521,18 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
 					if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end())
 					{
 						names_requested.push_back(owner_id);
-						gCacheName->get(owner_id, is_group_owned,  // username
-							boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
-							    this, _1, _2));
+						if (is_group_owned)
+						{
+							gCacheName->getGroup(owner_id,
+								boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
+								    this, _1, _2));
+						}
+						else
+						{
+							LLAvatarNameCache::get(owner_id,
+								boost::bind(&LLPanelScriptLimitsRegionMemory::onAvatarNameCache,
+								    this, _1, _2));
+						}
 					}
 				}
 			}
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 2ac3862b4f..16450c6527 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -38,6 +38,7 @@
 
 class LLPanelScriptLimitsInfo;
 class LLTabContainer;
+class LLAvatarName;
 
 class LLPanelScriptLimitsRegionMemory;
 
@@ -116,6 +117,8 @@ public:
 	void checkButtonsEnabled();
 
 private:
+	void onAvatarNameCache(const LLUUID& id,
+						 const LLAvatarName& av_name);
 	void onNameCache(const LLUUID& id,
 						 const std::string& name);
 
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index b2271cf4ff..3ab8fed2c6 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -36,6 +36,7 @@
 #include "llagentdata.h"
 #include "llagentui.h"
 #include "llagentwearables.h"
+#include "llavatarnamecache.h"
 #include "llfloatertools.h" // for gFloaterTool
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
@@ -327,12 +328,12 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im
 	// If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history.
 	else
 	{
-		std::string full_name;
-		if (gCacheName->getFullName(to_agent, full_name))
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(to_agent, &av_name))
 		{
 			// Build a new format username or firstname_lastname for legacy names
 			// to use it for a history log filename.
-			full_name = LLCacheName::buildUsername(full_name);
+			std::string full_name = LLCacheName::buildUsername(av_name.getUserName());
 			LLUIString message = LLTrans::getString(message_name + "-im");
 			message.setArgs(args);
 			LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, message.getString());
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 7545112ab9..152d0eddcd 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -38,6 +38,7 @@
 
 #include "llappviewer.h"
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llui.h"
 #include "message.h"
 #include "roles_constants.h"
@@ -54,6 +55,7 @@
 #include <boost/regex.hpp>
 #include "llcorehttputil.h"
 
+
 #if LL_MSVC
 #pragma warning(push)   
 // disable boost::lexical_cast warning
@@ -819,9 +821,9 @@ void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
 	LLGroupMgr::getInstance()->sendGroupMemberEjects(mID, ids);
 	LLGroupMgr::getInstance()->sendGroupMembersRequest(mID);
 	LLSD args;
-	std::string name;
-	gCacheName->getFullName(participant_uuid, name);
-	args["AVATAR_NAME"] = name;
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(participant_uuid, &av_name);
+	args["AVATAR_NAME"] = av_name.getUserName();
 	args["GROUP_NAME"] = mName;
 	LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
 }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 2e9332c355..ff8b8b0403 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -646,6 +646,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 	std::string you_joined_call = LLTrans::getString("you_joined_call");
 	std::string you_started_call = LLTrans::getString("you_started_call");
 	std::string other_avatar_name = "";
+	LLAvatarName av_name;
 
 	std::string message;
 
@@ -655,7 +656,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 		// no text notifications
 		break;
 	case P2P_SESSION:
-		gCacheName->getFullName(mOtherParticipantID, other_avatar_name); // voice
+		LLAvatarNameCache::get(mOtherParticipantID, &av_name);
+		other_avatar_name = av_name.getUserName();
 
 		if(direction == LLVoiceChannel::INCOMING_CALL)
 		{
@@ -806,7 +808,7 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
 		{
 			// convert it to a legacy name if we have a complete name
 			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
+			from_id = LLAvatarNameCache::findIdByName(legacy_name);
 		}
 
 		std::string timestamp = msg[LL_IM_TIME];
@@ -2765,10 +2767,10 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 
 		else
 		{
-			std::string session_name;
+			LLAvatarName av_name;
 			// since we select user to share item with - his name is already in cache
-			gCacheName->getFullName(args["user_id"], session_name);
-			session_name = LLCacheName::buildUsername(session_name);
+			LLAvatarNameCache::get(args["user_id"], &av_name);
+			std::string session_name = LLCacheName::buildUsername(av_name.getUserName());
 			LLIMModel::instance().logToFile(session_name, SYSTEM_FROM, LLUUID::null, message.getString());
 		}
 	}
@@ -3075,8 +3077,8 @@ void LLIMMgr::inviteToSession(
 	{
 		if (caller_name.empty())
 		{
-			gCacheName->get(caller_id, false,  // voice
-				boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3));
+			LLAvatarNameCache::get(caller_id, 
+				boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2));
 		}
 		else
 		{
@@ -3095,9 +3097,9 @@ void LLIMMgr::inviteToSession(
 	}
 }
 
-void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group)
+void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const LLAvatarName& av_name)
 {
-	payload["caller_name"] = name;
+	payload["caller_name"] = av_name.getUserName();
 	payload["session_name"] = payload["caller_name"].asString();
 
 	std::string notify_box_type = payload["notify_box_type"].asString();
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index da40ac8393..e3851a56e0 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -473,7 +473,7 @@ private:
 
 	void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
 
-	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
+	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const LLAvatarName& name);
 
 	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg);
     //Triggers when a session has already been added
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 287fa4c45b..855f7c750e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -34,6 +34,7 @@
 #include "llagent.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
+#include "llavatarnamecache.h"
 #include "llclipboard.h"
 #include "llinventorypanel.h"
 #include "llinventorybridge.h"
@@ -1022,19 +1023,19 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 		{
 			// Valid UUID; set the item UUID and rename it
 			new_item->setCreator(id);
-			std::string avatar_name;
+			LLAvatarName av_name;
 
-			if (gCacheName->getFullName(id, avatar_name))
+			if (LLAvatarNameCache::get(id, &av_name))
 			{
-				new_item->rename(avatar_name);
+				new_item->rename(av_name.getUserName());
 				mask |= LLInventoryObserver::LABEL;
 			}
 			else
 			{
 				// Fetch the current name
-				gCacheName->get(id, FALSE,
+				LLAvatarNameCache::get(id,
 					boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(),
-					_1, _2, _3));
+					_1, _2));
 			}
 
 		}
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 0f70c9d13f..3af9c2f912 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -53,6 +53,7 @@
 #include "llxfermanager.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llviewergenericmessage.h"	// for gGenericDispatcher
 #include "llworld.h" //for particle system banning
 #include "llimview.h"
@@ -456,7 +457,7 @@ void LLMuteList::updateRemove(const LLMute& mute)
 	gAgent.sendReliableMessage();
 }
 
-void notify_automute_callback(const LLUUID& agent_id, const std::string& full_name, bool is_group, LLMuteList::EAutoReason reason)
+void notify_automute_callback(const LLUUID& agent_id, const LLAvatarName& full_name, LLMuteList::EAutoReason reason)
 {
 	std::string notif_name;
 	switch (reason)
@@ -474,7 +475,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& full_na
 	}
 
 	LLSD args;
-	args["NAME"] = full_name;
+	args["NAME"] = full_name.getUserName();
     
 	LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args, LLSD());
 	if (notif_ptr)
@@ -499,17 +500,17 @@ BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason)
 		removed = TRUE;
 		remove(automute);
 
-		std::string full_name;
-		if (gCacheName->getFullName(agent_id, full_name))
-			{
-				// name in cache, call callback directly
-			notify_automute_callback(agent_id, full_name, false, reason);
-			}
-			else
-			{
-				// not in cache, lookup name from cache
-			gCacheName->get(agent_id, false,
-				boost::bind(&notify_automute_callback, _1, _2, _3, reason));
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(agent_id, &av_name))
+		{
+			// name in cache, call callback directly
+			notify_automute_callback(agent_id, av_name, reason);
+		}
+		else
+		{
+			// not in cache, lookup name from cache
+			LLAvatarNameCache::get(agent_id,
+				boost::bind(&notify_automute_callback, _1, _2, reason));
 		}
 	}
 
diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp
index 1099316a19..8d32fb1d5c 100644
--- a/indra/newview/llnamebox.cpp
+++ b/indra/newview/llnamebox.cpp
@@ -35,6 +35,7 @@
 #include "lluuid.h"
 
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 
 // statics
 std::set<LLNameBox*> LLNameBox::sInstances;
@@ -67,7 +68,9 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group)
 
 	if (!is_group)
 	{
-		got_name = gCacheName->getFullName(name_id, name);
+		LLAvatarName av_name;
+		got_name = LLAvatarNameCache::get(name_id, &av_name);
+		name = av_name.getUserName();
 	}
 	else
 	{
diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp
index b3b1ff7c06..055754f270 100644
--- a/indra/newview/llnameeditor.cpp
+++ b/indra/newview/llnameeditor.cpp
@@ -28,6 +28,7 @@
  
 #include "llnameeditor.h"
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 
 #include "llfontgl.h"
 
@@ -65,7 +66,9 @@ void LLNameEditor::setNameID(const LLUUID& name_id, BOOL is_group)
 
 	if (!is_group)
 	{
-		gCacheName->getFullName(name_id, name);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(name_id, &av_name);
+		name = av_name.getUserName();
 	}
 	else
 	{
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index a078889d46..4a3923ef6e 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -114,11 +114,11 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 	}
 }
 
-void log_name_callback(const std::string& full_name, const std::string& from_name, 
+void log_name_callback(const LLAvatarName& av_name, const std::string& from_name, 
 					   const std::string& message, const LLUUID& from_id)
 
 {
-	LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, full_name, from_name, message,
+	LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, av_name.getUserName(), from_name, message,
 					from_id, LLUUID());
 }
 
@@ -141,11 +141,11 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
 
 	if(to_file_only)
 	{
-		gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
 	}
 	else
 	{
-		gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
 	}
 }
 
@@ -167,9 +167,18 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 	const std::string group_name = groupData.mName;
 	const std::string sender_name = payload["sender_name"].asString();
 
-	// we can't retrieve sender id from group notice system message, so try to lookup it from cache
 	LLUUID sender_id;
-	gCacheName->getUUID(sender_name, sender_id);
+	if (payload.has("sender_id"))
+	{
+		sender_id = payload["sender_id"].asUUID();
+	}
+	
+	if (sender_id.notNull())
+	{
+		// Legacy support and fallback method
+		// if we can't retrieve sender id from group notice system message, try to lookup it from cache
+		sender_id = LLAvatarNameCache::findIdByName(sender_name);
+	}
 
 	logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"],
 			payload["group_id"], sender_id);
@@ -219,7 +228,12 @@ std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notifica
 		{
 			from_id = notification->getPayload()["from_id"];
 		}
-		if(!gCacheName->getFullName(from_id, res))
+		LLAvatarName av_name;
+		if(LLAvatarNameCache::get(from_id, &av_name))
+		{
+			res = av_name.getUserName();
+		}
+		else
 		{
 			res = "";
 		}
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 6ac439177a..8440e9ee50 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1168,9 +1168,9 @@ void LLPanelGroupMembersSubTab::confirmEjectMembers()
 	if (selection_count == 1)
 	{
 		LLSD args;
-		std::string fullname;
-		gCacheName->getFullName(mMembersList->getValue(), fullname);
-		args["AVATAR_NAME"] = fullname;
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(mMembersList->getValue(), &av_name);
+		args["AVATAR_NAME"] = av_name.getUserName();
 		LLSD payload;
 		LLNotificationsUtil::add("EjectGroupMemberWarning",
 				 	 	 	 	 args,
@@ -1862,9 +1862,9 @@ void LLPanelGroupMembersSubTab::confirmBanMembers()
 	if (selection_count == 1)
 	{
 		LLSD args;
-		std::string fullname;
-		gCacheName->getFullName(mMembersList->getValue(), fullname);
-		args["AVATAR_NAME"] = fullname;
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(mMembersList->getValue(), &av_name);
+		args["AVATAR_NAME"] = av_name.getUserName();
 		LLSD payload;
 		LLNotificationsUtil::add("BanGroupMemberWarning",
 				 	 	 	 	 args,
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 55c09d85ea..77bc99da83 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -384,9 +384,9 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 		LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
 		if(avatar_picks && getAvatarId() == avatar_picks->target_id)
 		{
-			std::string full_name;
-			gCacheName->getFullName(getAvatarId(), full_name);
-			getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", full_name);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(getAvatarId(), &av_name);
+			getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName());
 			
 			// Save selection, to be able to edit same item after saving changes. See EXT-3023.
 			LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index ee7c22800a..5ebf7cfe13 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -33,6 +33,7 @@
 
 // library includes
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 #include "lldbstrings.h"
 #include "lleconomy.h"
 #include "llgl.h"
@@ -5385,9 +5386,9 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use
 		LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
 		if (reporterp)
 		{
-			std::string fullname;
-			gCacheName->getFullName(owner_id, fullname);
-			reporterp->setPickedObjectProperties(name, fullname, owner_id);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(owner_id, &av_name);
+			reporterp->setPickedObjectProperties(name, av_name.getUserName(), owner_id);
 		}
 	}
 	else if (request_flags & OBJECT_PAY_REQUEST)
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index e7971028bf..19d1af34f9 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -29,6 +29,7 @@
 #include "llspeakers.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llappviewer.h"
 #include "llimview.h"
 #include "llgroupmgr.h"
@@ -75,13 +76,13 @@ void LLSpeaker::lookupName()
 {
 	if (mDisplayName.empty())
 	{
-		gCacheName->get(mID, false, boost::bind(&LLSpeaker::onNameCache, this, _1, _2, _3));
+		LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _1, _2)); // todo: can be group???
 	}
 }
 
-void LLSpeaker::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
+void LLSpeaker::onNameCache(const LLUUID& id, const LLAvatarName& av_name)
 {
-	mDisplayName = full_name;
+	mDisplayName = av_name.getUserName();
 }
 
 bool LLSpeaker::isInVoiceChannel()
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 617bae3984..d1dbf72fe9 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -34,6 +34,7 @@
 #include "llcoros.h"
 
 class LLSpeakerMgr;
+class LLAvatarName;
 
 // data for a given participant in a voice channel
 class LLSpeaker : public LLRefCount, public LLOldEvents::LLObservable, public LLHandleProvider<LLSpeaker>, public boost::signals2::trackable
@@ -61,7 +62,7 @@ public:
 	~LLSpeaker() {};
 	void lookupName();
 
-	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
+	void onNameCache(const LLUUID& id, const LLAvatarName& full_name);
 
 	bool isInVoiceChannel();
 
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 27c4c90857..49436ee406 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1584,12 +1584,12 @@ static void show_object_sharing_confirmation(const std::string name,
 }
 
 static void get_name_cb(const LLUUID& id,
-						const std::string& full_name,
+						const LLAvatarName& av_name,
 						LLInventoryObject* inv_obj,
 						const LLSD& dest,
 						const LLUUID& dest_agent)
 {
-	show_object_sharing_confirmation(full_name,
+	show_object_sharing_confirmation(av_name.getUserName(),
 								     inv_obj,
 								     dest,
 						  		     id,
@@ -1634,17 +1634,17 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
 				// If no IM session found get the destination agent's name by id.
 				if (NULL == session)
 				{
-					std::string fullname;
+					LLAvatarName av_name;
 
 					// If destination agent's name is found in cash proceed to showing the confirmation dialog.
 					// Otherwise set up a callback to show the dialog when the name arrives.
-					if (gCacheName->getFullName(dest_agent, fullname))
+					if (LLAvatarNameCache::get(dest_agent, &av_name))
 					{
-						show_object_sharing_confirmation(fullname, inv_obj, dest, dest_agent, LLUUID::null);
+						show_object_sharing_confirmation(av_name.getUserName(), inv_obj, dest, dest_agent, LLUUID::null);
 					}
 					else
 					{
-						gCacheName->get(dest_agent, false, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent));
+						LLAvatarNameCache::get(dest_agent, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent));
 					}
 
 					return true;
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index e79ce55854..9acf9080bf 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -883,7 +883,7 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 		}
 		else if (hover_parcel->getIsGroupOwned())
 		{
-			if (gCacheName->getGroupName(owner, name))
+			if (gCacheName->getFullName(owner, name)) //group?
 			{
 				line.append(name);
 				line.append(LLTrans::getString("TooltipIsGroup"));
@@ -893,14 +893,19 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 				line.append(LLTrans::getString("RetrievingData"));
 			}
 		}
-		else if(gCacheName->getFullName(owner, name))
-		{
-			line.append(name);
-		}
-		else
-		{
-			line.append(LLTrans::getString("RetrievingData"));
-		}
+        else
+        {
+            LLAvatarName av_name;
+            if (LLAvatarNameCache::get(owner, &av_name))
+            {
+                name = av_name.getUserName();
+                line.append(name);
+            }
+            else
+            {
+                line.append(LLTrans::getString("RetrievingData"));
+            }
+        }
 	}
 	else
 	{
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index caffeadb73..bf79a0595c 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1126,10 +1126,10 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
 void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent /*= LLUUID::null*/, LLPointer<LLInventoryCallback> cb/*=NULL*/)
 {
 	std::string item_desc = avatar_id.asString();
-	std::string item_name;
-	gCacheName->getFullName(avatar_id, item_name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(avatar_id, &av_name);
 	create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
-						  parent, LLTransactionID::tnull, item_name, item_desc, LLAssetType::AT_CALLINGCARD,
+						  parent, LLTransactionID::tnull, av_name.getUserName(), item_desc, LLAssetType::AT_CALLINGCARD,
 						  LLInventoryType::IT_CALLINGCARD, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
 }
 
@@ -2071,9 +2071,9 @@ PermissionMask LLViewerInventoryItem::getPermissionMask() const
 
 //----------
 
-void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group)
+void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const LLAvatarName& name)
 {
-	rename(name);
+	rename(name.getUserName());
 	gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID());
 	gInventory.notifyObservers();
 }
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 074d51b8b3..b3053e365b 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -39,6 +39,7 @@ class LLFolderView;
 class LLFolderBridge;
 class LLViewerInventoryCategory;
 class LLInventoryCallback;
+class LLAvatarName;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLViewerInventoryItem
@@ -158,7 +159,7 @@ public:
 	PermissionMask getPermissionMask() const;
 
 	// callback
-	void onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group);
+	void onCallingCardNameLookup(const LLUUID& id, const LLAvatarName& name);
 
 	// If this is a broken link, try to fix it and any other identical link.
 	BOOL regenerateLink();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index d847661ce7..a92ecd2036 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6560,10 +6560,10 @@ class LLMuteParticle : public view_listener_t
 		
 		if (id.notNull())
 		{
-			std::string name;
-			gCacheName->getFullName(id, name);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(id, &av_name);
 
-			LLMute mute(id, name, LLMute::AGENT);
+			LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 			if (LLMuteList::getInstance()->isMuted(mute.mID))
 			{
 				LLMuteList::getInstance()->remove(mute);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8076c6b1df..ab76653ba6 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1390,6 +1390,14 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 			gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
 }
 
+
+void inventory_offer_mute_avatar_callback(const LLUUID& blocked_id,
+    const LLAvatarName& av_name)
+{
+    inventory_offer_mute_callback(blocked_id, av_name.getUserName(), false);
+}
+
+
 std::string LLOfferInfo::mResponderType = "offer_info";
 
 LLOfferInfo::LLOfferInfo()
@@ -1538,7 +1546,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	{
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			if (mFromGroup)
+			{
+				gCacheName->getGroup(mFromID, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			}
+			else
+			{
+				LLAvatarNameCache::get(mFromID, boost::bind(&inventory_offer_mute_avatar_callback, _1, _2));
+			}
 		}
 	}
 
@@ -1695,7 +1710,14 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			if (mFromGroup)
+			{
+				gCacheName->getGroup(mFromID, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			}
+			else
+			{
+				LLAvatarNameCache::get(mFromID, boost::bind(&inventory_offer_mute_avatar_callback, _1, _2));
+			}
 		}
 	}
 	
@@ -1744,12 +1766,12 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		}
 		else
 		{
-			std::string full_name;
-			if (gCacheName->getFullName(mFromID, full_name))
+			LLAvatarName av_name;
+			if (LLAvatarNameCache::get(mFromID, &av_name))
 			{
 				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName 
-					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + full_name;
-				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + full_name;
+					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + av_name.getUserName();
+				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + av_name.getUserName();
 			}
 			else
 			{
@@ -2601,9 +2623,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{
 				original_name = original_name.substr(0, index);
 			}
+
 			std::string legacy_name = gCacheName->buildLegacyName(original_name);
-			LLUUID agent_id;
-			gCacheName->getUUID(legacy_name, agent_id);
+			LLUUID agent_id = LLAvatarNameCache::findIdByName(legacy_name);
 
 			if (agent_id.isNull())
 			{
@@ -2662,6 +2684,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				payload["subject"] = subj;
 				payload["message"] = mes;
 				payload["sender_name"] = name;
+				payload["sender_id"] = agent_id;
 				payload["group_id"] = group_id;
 				payload["inventory_name"] = item_name;
  				payload["received_time"] = LLDate::now();
@@ -6183,7 +6206,7 @@ void handle_show_mean_events(void *)
 	//LLFloaterBump::showInstance();
 }
 
-void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
+void mean_name_callback(const LLUUID &id, const LLAvatarName& av_name)
 {
 	static const U32 max_collision_list_size = 20;
 	if (gMeanCollisionList.size() > max_collision_list_size)
@@ -6200,7 +6223,7 @@ void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_
 		LLMeanCollisionData *mcd = *iter;
 		if (mcd->mPerp == id)
 		{
-			mcd->mFullName = full_name;
+			mcd->mFullName = av_name.getUserName();
 		}
 	}
 }
@@ -6254,7 +6277,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
 		{
 			LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
 			gMeanCollisionList.push_front(mcd);
-			gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));
+			LLAvatarNameCache::get(perp, boost::bind(&mean_name_callback, _1, _2));
 		}
 	}
 	LLFloaterBump* bumps_floater = LLFloaterBump::getInstance();
@@ -7031,8 +7054,8 @@ void send_lures(const LLSD& notification, const LLSD& response)
 
 		// Record the offer.
 		{
-			std::string target_name;
-			gCacheName->getFullName(target_id, target_name);  // for im log filenames
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(target_id, &av_name);  // for im log filenames
 			LLSD args;
 			args["TO_NAME"] = LLSLURL("agent", target_id, "completename").getSLURLString();;
 	
@@ -7117,10 +7140,10 @@ bool teleport_request_callback(const LLSD& notification, const LLSD& response)
 		return false;
 	}
 
-	std::string from_name;
-	gCacheName->getFullName(from_id, from_name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(from_id, &av_name);
 
-	if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(from_name))
+	if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(av_name.getUserName()))
 	{
 		return false;
 	}
@@ -7395,8 +7418,7 @@ bool callback_load_url(const LLSD& notification, const LLSD& response)
 }
 static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
 
-
-// We've got the name of the person who owns the object hurling the url.
+// We've got the name of the person or group that owns the object hurling the url.
 // Display confirmation dialog.
 void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group)
 {
@@ -7438,6 +7460,12 @@ void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool
 	}
 }
 
+// We've got the name of the person who owns the object hurling the url.
+void callback_load_url_avatar_name(const LLUUID& id, const LLAvatarName& av_name)
+{
+    callback_load_url_name(id, av_name.getUserName(), false);
+}
+
 void process_load_url(LLMessageSystem* msg, void**)
 {
 	LLUUID object_id;
@@ -7475,8 +7503,14 @@ void process_load_url(LLMessageSystem* msg, void**)
 	// Add to list of pending name lookups
 	gLoadUrlList.push_back(payload);
 
-	gCacheName->get(owner_id, owner_is_group,
-		boost::bind(&callback_load_url_name, _1, _2, _3));
+	if (owner_is_group)
+	{
+		gCacheName->getGroup(owner_id, boost::bind(&callback_load_url_name, _1, _2, _3));
+	}
+	else
+	{
+		LLAvatarNameCache::get(owner_id, boost::bind(&callback_load_url_avatar_name, _1, _2));
+	}
 }
 
 
-- 
cgit v1.2.3


From 49b448b7782811949560d155c273ac8444e25fc1 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 22 Feb 2017 18:31:12 +0200
Subject: MAINT-7118 fixed erroneous name check

---
 indra/newview/lltoolpie.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 9acf9080bf..fc052ae3aa 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -883,7 +883,7 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 		}
 		else if (hover_parcel->getIsGroupOwned())
 		{
-			if (gCacheName->getFullName(owner, name)) //group?
+			if (gCacheName->getGroupName(owner, name))
 			{
 				line.append(name);
 				line.append(LLTrans::getString("TooltipIsGroup"));
-- 
cgit v1.2.3


From f88881884fe3fd72eb0cada7cb23095ae53f8658 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 23 Feb 2017 12:17:59 +0200
Subject: MAINT-7138 Fix Agent Limit field and spinner cap in Region/Estate
 floater

---
 indra/llmessage/message_prehash.cpp   | 1 +
 indra/llmessage/message_prehash.h     | 1 +
 indra/newview/llfloaterregioninfo.cpp | 4 ++++
 indra/newview/llregioninfomodel.cpp   | 4 ++++
 indra/newview/llregioninfomodel.h     | 2 ++
 5 files changed, 12 insertions(+)

diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 5c6b3d5fab..6675e12649 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -618,6 +618,7 @@ char const* const _PREHASH_GroupAccountSummaryRequest = LLMessageStringTable::ge
 char const* const _PREHASH_GroupVoteHistoryRequest = LLMessageStringTable::getInstance()->getString("GroupVoteHistoryRequest");
 char const* const _PREHASH_ParamValue = LLMessageStringTable::getInstance()->getString("ParamValue");
 char const* const _PREHASH_MaxAgents = LLMessageStringTable::getInstance()->getString("MaxAgents");
+char const* const _PREHASH_HardMaxAgents = LLMessageStringTable::getInstance()->getString("HardMaxAgents");
 char const* const _PREHASH_CreateNewOutfitAttachments = LLMessageStringTable::getInstance()->getString("CreateNewOutfitAttachments");
 char const* const _PREHASH_RegionHandle = LLMessageStringTable::getInstance()->getString("RegionHandle");
 char const* const _PREHASH_TeleportProgress = LLMessageStringTable::getInstance()->getString("TeleportProgress");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index e696c3b0ca..a510b4498f 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -618,6 +618,7 @@ extern char const* const _PREHASH_GroupAccountSummaryRequest;
 extern char const* const _PREHASH_GroupVoteHistoryRequest;
 extern char const* const _PREHASH_ParamValue;
 extern char const* const _PREHASH_MaxAgents;
+extern char const* const _PREHASH_HardMaxAgents;
 extern char const* const _PREHASH_CreateNewOutfitAttachments;
 extern char const* const _PREHASH_RegionHandle;
 extern char const* const _PREHASH_TeleportProgress;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 843dbbf25e..75d7d787b1 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -357,6 +357,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	std::string sim_type = LLTrans::getString("land_type_unknown");
 	U64 region_flags;
 	U8 agent_limit;
+	S32 hard_agent_limit;
 	F32 object_bonus_factor;
 	U8 sim_access;
 	F32 water_height;
@@ -366,6 +367,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	F32 sun_hour;
 	msg->getString("RegionInfo", "SimName", sim_name);
 	msg->getU8("RegionInfo", "MaxAgents", agent_limit);
+	msg->getS32("RegionInfo2", "HardMaxAgents", hard_agent_limit);
 	msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
 	msg->getU8("RegionInfo", "SimAccess", sim_access);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
@@ -412,6 +414,8 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	panel->getChild<LLUICtrl>("object_bonus_spin")->setValue(LLSD(object_bonus_factor) );
 	panel->getChild<LLUICtrl>("access_combo")->setValue(LLSD(sim_access) );
 
+	panel->getChild<LLSpinCtrl>("agent_limit_spin")->setMaxValue(hard_agent_limit);
+
 	LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral();
 	if (panel)
 	{
diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp
index 25c576468b..25d7be831f 100644
--- a/indra/newview/llregioninfomodel.cpp
+++ b/indra/newview/llregioninfomodel.cpp
@@ -40,6 +40,7 @@ void LLRegionInfoModel::reset()
 {
 	mSimAccess			= 0;
 	mAgentLimit			= 0;
+	mHardAgentLimit		= 100;
 
 	mRegionFlags		= 0;
 	mEstateID			= 0;
@@ -143,6 +144,7 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit);
+
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, mBillableFactor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, mWaterHeight);
@@ -158,6 +160,8 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour);
 	LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL;
 
+	msg->getS32Fast(_PREHASH_RegionInfo2, _PREHASH_HardMaxAgents, mHardAgentLimit);
+
 	if (msg->has(_PREHASH_RegionInfo3))
 	{
 		msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, mRegionFlags);
diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h
index ea9640efda..baeff82fef 100644
--- a/indra/newview/llregioninfomodel.h
+++ b/indra/newview/llregioninfomodel.h
@@ -53,6 +53,8 @@ public:
 	U8			mSimAccess;
 	U8			mAgentLimit;
 
+	S32			mHardAgentLimit;
+
 	U64			mRegionFlags;
 	U32			mEstateID;
 	U32			mParentEstateID;
-- 
cgit v1.2.3


From 043d13d5e48b1397de1f84cb19b7d2d85a9757f1 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 23 Feb 2017 19:38:12 +0200
Subject: MAINT-2132 Fixed Avatar hasn't animation while moving if wear and
 detach object in edit mode

---
 indra/newview/llselectmgr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 5ebf7cfe13..353c61da0c 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6619,7 +6619,7 @@ void LLSelectMgr::updateSelectionCenter()
 	{
 		mSelectedObjects->mSelectType = getSelectTypeForObject(object);
 
-		if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
+		if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid() && object->getParent() != NULL)
 		{
 			mPauseRequest = gAgentAvatarp->requestPause();
 		}
-- 
cgit v1.2.3


From fd756828a762082c8ae4fa3d69516241ecb1b858 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 24 Feb 2017 17:41:39 +0200
Subject: MAINT-3509 Fixed Context menu orphaned when Inventory floater is
 closed by keyboard shortcut

---
 indra/llui/llmenugl.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8425774d46..022f814bbc 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3342,6 +3342,12 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
+	if (result && !getHighlightedItem() && LLMenuGL::sMenuContainer->hasVisibleMenu())
+	{
+		// close menus originating from other menu bars
+		LLMenuGL::sMenuContainer->hideMenus();
+	}
+
 	return result;
 }
 
-- 
cgit v1.2.3


From ba99caa574d1e346aecf2f0fe39d46d340f8afbf Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 27 Feb 2017 16:43:17 +0200
Subject: MAINT-1206 "Save as" only works once when making skins in the new
 appearance editor

---
 indra/newview/llsidepanelappearance.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 3e95811bb8..d6bf2164a0 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -388,7 +388,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearab
 		return;
 	}
 
-	if (mEditWearable->getVisible() == visible && (!visible || mEditWearable->getWearable() != wearable))
+	if (mEditWearable->getVisible() == visible && (!visible || mEditWearable->getWearable() == wearable))
 	{
 		// visibility isn't changing and panel doesn't need an update, hence nothing to do
 		return;
-- 
cgit v1.2.3


From 6c80f7369aaf2cddea55e288b5c402fba54f5d98 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Mon, 27 Feb 2017 19:27:18 +0200
Subject: MAINT-3235 Stand button not centered when left toolbar is empty

---
 indra/newview/llmoveview.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index c3dd08c327..4999318973 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -730,9 +730,16 @@ void LLPanelStandStopFlying::updatePosition()
 		panel_ssf_container->setOrigin(0, y_pos);
 	}
 
-	S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width;
-
-	setOrigin( x_pos, 0);
+	if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons())
+	{
+		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width;
+		setOrigin( x_pos, 0);
+	}
+	else 
+	{
+		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2;
+		setOrigin( x_pos, 0);
+	}
 }
 
 // EOF
-- 
cgit v1.2.3


From 9bd3a99f20ff6e73f5ea2245a21a94c5882ca673 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 28 Feb 2017 18:34:18 +0200
Subject: MAINT-908 Build Tool has wrong screen priority and can stay behind
 other floaters when called

---
 indra/newview/llviewermenu.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a92ecd2036..605d1a04e6 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8402,6 +8402,15 @@ class LLToolsSelectTool : public view_listener_t
 		{
 			LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5);
 		}
+
+		// Note: if floater is not visible LLViewerWindow::updateLayout() will
+		// attempt to open it, but it won't bring it to front or de-minimize.
+		if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost()))
+		{
+			gFloaterTools->setMinimized(FALSE);
+			gFloaterTools->openFloater();
+			gFloaterTools->setVisibleAndFrontmost(TRUE);
+		}
 		return true;
 	}
 };
-- 
cgit v1.2.3


From b4c4a951c161e43bf66141248f0c94b97848ae98 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 1 Mar 2017 17:53:26 +0200
Subject: MAINT-3604 Extend llTextBox message lines according to it's length

---
 indra/newview/lltoastscripttextbox.cpp             | 57 +++++++++-------
 indra/newview/lltoastscripttextbox.h               |  3 +
 .../skins/default/xui/en/panel_notify_textbox.xml  | 78 ++++++++++++----------
 3 files changed, 79 insertions(+), 59 deletions(-)

diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 78d9e92b5c..776ae2ece9 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -28,31 +28,21 @@
 
 #include "lltoastscripttextbox.h"
 
-#include "llfocusmgr.h"
-
-#include "llbutton.h"
+#include "lllslconstants.h"
 #include "llnotifications.h"
-#include "llviewertexteditor.h"
-
-#include "llavatarnamecache.h"
-#include "lluiconstants.h"
-#include "llui.h"
-#include "llviewercontrol.h"
-#include "lltrans.h"
 #include "llstyle.h"
+#include "lluiconstants.h"
+#include "llviewertexteditor.h"
 
-#include "llglheaders.h"
-#include "llagent.h"
-
-const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 7;
+const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 14;
 
 LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification)
 :	LLToastPanel(notification)
 {
 	buildFromFile( "panel_notify_textbox.xml");
 
-	LLTextEditor* text_editorp = getChild<LLTextEditor>("text_editor_box");
-	text_editorp->setValue(notification->getMessage());
+	mInfoText = getChild<LLTextBox>("text_editor_box");
+	mInfoText->setValue(notification->getMessage());
 
 	getChild<LLButton>("ignore_btn")->setClickedCallback(boost::bind(&LLToastScriptTextbox::onClickIgnore, this));
 
@@ -73,13 +63,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
 	pSubmitBtn->setClickedCallback((boost::bind(&LLToastScriptTextbox::onClickSubmit, this)));
 	setDefaultBtn(pSubmitBtn);
 
-	S32 maxLinesCount;
-	std::istringstream ss( getString("message_max_lines_count") );
-	if (!(ss >> maxLinesCount))
-	{
-		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
-	}
-	//snapToMessageHeight(pMessageText, maxLinesCount);
+	snapToMessageHeight();
 }
 
 // virtual
@@ -92,7 +76,6 @@ void LLToastScriptTextbox::close()
 	die();
 }
 
-#include "lllslconstants.h"
 void LLToastScriptTextbox::onClickSubmit()
 {
 	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");
@@ -119,3 +102,29 @@ void LLToastScriptTextbox::onClickIgnore()
 	mNotification->respond(response);
 	close();
 }
+
+void LLToastScriptTextbox::snapToMessageHeight()
+{
+	LLPanel* info_pan = getChild<LLPanel>("info_panel");
+	if (!info_pan)
+	{
+		return;
+	}
+
+	S32 maxLinesCount;
+	std::istringstream ss( getString("message_max_lines_count") );
+	if (!(ss >> maxLinesCount))
+	{
+		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+	}
+
+
+	S32 maxTextHeight = (mInfoText->getFont()->getLineHeight() * maxLinesCount);
+	S32 oldTextHeight = mInfoText->getRect().getHeight();
+	S32 newTextHeight = llmin(mInfoText->getTextBoundingRect().getHeight(), maxTextHeight);
+
+	S32 heightDelta = newTextHeight - oldTextHeight;
+
+	reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+	info_pan->reshape(info_pan->getRect().getWidth(),newTextHeight);
+}
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
index 7d33446248..7aee02dd00 100644
--- a/indra/newview/lltoastscripttextbox.h
+++ b/indra/newview/lltoastscripttextbox.h
@@ -48,9 +48,12 @@ public:
 
 private:
 
+	LLTextBox* mInfoText;
+
 	void onClickSubmit();
 	void onClickIgnore();
 
+	void snapToMessageHeight();
 	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
 };
 
diff --git a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
index d5b6057233..a679ca7f8c 100644
--- a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
    background_visible="true"
-   height="220"
+   height="215"
    label="instant_message"
    layout="topleft"
    left="0"
@@ -10,21 +10,19 @@
    width="305">
   <string
      name="message_max_lines_count"
-     value="7" />
+     value="14" />
   <panel
-   bevel_style="none"
-   follows="left|right|top"
-   height="185"
-   label="info_panel"
-   layout="topleft"
-   left="0"
-   name="info_panel"
-   top="0"
-   width="305">    
-    <text_editor
-     bg_readonly_color="0.0 0.0 0.0 0"
-     enabled="false"
-     follows="left|right|top|bottom"
+     bevel_style="none"
+     follows="all"
+     height="120"
+     label="info_panel"
+     layout="topleft"
+     left="0"
+     name="info_panel"
+     top="0"
+     width="305">
+    <text
+     follows="all"
      font="SansSerif"
      height="110" 
      layout="topleft"
@@ -34,30 +32,40 @@
      read_only="true"
      text_color="white"
      text_readonly_color="white"
-     top="10"
+     top="0"
      width="285"
      wrap="true"
      parse_highlights="true"
      parse_urls="true"/>
-    <text_editor
-     parse_urls="true"
-     enabled="true"
-     follows="all"
-     height="50"
+  </panel> 
+  <panel
+     bevel_style="none"
+     follows="left|right|bottom"
+     height="55"
+     label="info_panel"
      layout="topleft"
-     left="10"
-     max_length="250"
-     name="message"
-     parse_highlights="true"
-     read_only="false"
-     top_pad="10"
-     type="string"
-     use_ellipses="true"
-     value="message"
-     width="285"
-     word_wrap="true"
-     parse_url="false" >
-    </text_editor>
+     left="0"
+     name="textbox_panel"
+     top_pad="5"
+     width="305">  
+     <text_editor
+      parse_urls="true"
+      enabled="true"
+      follows="all"
+      height="50"
+      layout="topleft"
+      left="10"
+      max_length="250"
+      name="message"
+      parse_highlights="true"
+      read_only="false"
+      top ="0"
+      type="string"
+      use_ellipses="true"
+      value="message"
+      width="285"
+      word_wrap="true">
+     </text_editor>
   </panel>
   <panel
      background_visible="false"
@@ -68,7 +76,7 @@
      layout="topleft"
      left="10"
      name="control_panel"
-     top_pad="0">
+     top_pad="5">
     <!-- 
 	 Notes:
 	 This panel holds the Ignore button and possibly other buttons of notification.
-- 
cgit v1.2.3


From ef8c1b7e7b826da125cb080306ea19c5cefaf215 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 2 Mar 2017 11:28:00 +0200
Subject: MAINT-7167 Change snapshot's social features to use "share" instead
 of "upload"

---
 indra/newview/skins/default/xui/en/panel_snapshot_options.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 265217ef60..305cce1cbe 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -48,7 +48,7 @@
    image_overlay_alignment="left"
    image_top_pad="-1"
    imgoverlay_label_space="10"
-   label="Upload to Profile"
+   label="Share to Profile Feed"
    layout="topleft"
    name="save_to_profile_btn"
    left_delta="0"
@@ -65,7 +65,7 @@
    image_overlay_alignment="left"
    image_top_pad="0"
    imgoverlay_label_space="10"
-   label="Upload to Facebook"
+   label="Share to Facebook"
    layout="topleft"
    left_delta="0"
    name="send_to_facebook_btn"
@@ -82,7 +82,7 @@
    image_overlay_alignment="left"
    image_top_pad="0"
    imgoverlay_label_space="10"
-   label="Upload to Twitter"
+   label="Share to Twitter"
    layout="topleft"
    left_delta="0"
    name="send_to_twitter_btn"
@@ -99,7 +99,7 @@
    image_overlay_alignment="left"
    image_top_pad="0"
    imgoverlay_label_space="10"
-   label="Upload to Flickr"
+   label="Share to Flickr"
    layout="topleft"
    left_delta="0"
    name="send_to_flickr_btn"
-- 
cgit v1.2.3


From 5bd5a474dd5582047fdbde2f0def0035db8b504a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 3 Mar 2017 17:26:07 +0200
Subject: MAINT-7168 SL Viewer should remember avatar rendering selection

---
 indra/newview/llvoavatar.cpp | 16 ++++++++++++++++
 indra/newview/llvoavatar.h   |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 8888879b8a..760eee17f3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -727,6 +727,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	{
 	    LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
 	}
+
+	mVisuallyMuteSetting = getSavedVisualMuteSettings();
 }
 
 std::string LLVOAvatar::avString() const
@@ -9228,12 +9230,26 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
     }
 }
 
+//static
+std::map<LLUUID, LLVOAvatar::VisualMuteSettings> LLVOAvatar::sVisuallyMuteSettingsMap;
+
 void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
 {
     mVisuallyMuteSetting = set;
     mNeedsImpostorUpdate = TRUE;
+    sVisuallyMuteSettingsMap[getID()] = set;
 }
 
+LLVOAvatar::VisualMuteSettings LLVOAvatar::getSavedVisualMuteSettings()
+{
+    std::map<LLUUID, VisualMuteSettings>::iterator iter = sVisuallyMuteSettingsMap.find(getID());
+    if (iter != sVisuallyMuteSettingsMap.end())
+    {
+        return iter->second;
+    }
+
+    return AV_RENDER_NORMALLY;
+}
 
 void LLVOAvatar::calcMutedAVColor()
 {
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index bd89d4ef23..73e4fbd108 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -407,6 +407,7 @@ public:
 	};
 	void		setVisualMuteSettings(VisualMuteSettings set);
 	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	};
+	VisualMuteSettings  getSavedVisualMuteSettings();
 
 	U32 		renderRigid();
 	U32 		renderSkinned();
@@ -440,6 +441,7 @@ public:
 
 	VisualMuteSettings		mVisuallyMuteSetting;			// Always or never visually mute this AV
 
+	static std::map<LLUUID, VisualMuteSettings> sVisuallyMuteSettingsMap;
 	//--------------------------------------------------------------------
 	// Morph masks
 	//--------------------------------------------------------------------
-- 
cgit v1.2.3


From 7040ae108ef60a17ad683cb0e9f81719a0270e51 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 2 Mar 2017 19:05:09 +0200
Subject: MAINT-7076 Add the ability to see/modify mute types within the block
 list

---
 indra/newview/llblocklist.cpp                      | 82 +++++++++++++++++++++-
 indra/newview/llblocklist.h                        |  3 +
 .../default/xui/en/menu_people_blocked_gear.xml    | 74 +++++++++++++++++++
 3 files changed, 157 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 272a68bdf7..08d6db4ceb 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -55,7 +55,9 @@ LLBlockList::LLBlockList(const Params& p)
 
 	registrar.add		("Block.Action",	boost::bind(&LLBlockList::onCustomAction,	this, _2));
 	enable_registrar.add("Block.Enable",	boost::bind(&LLBlockList::isActionEnabled,	this, _2));
-
+	enable_registrar.add("Block.Check",     boost::bind(&LLBlockList::isMenuItemChecked, this, _2));
+	enable_registrar.add("Block.Visible",   boost::bind(&LLBlockList::isMenuItemVisible, this, _2));
+	
 	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
 									"menu_people_blocked_gear.xml",
 									gMenuHolder,
@@ -272,7 +274,11 @@ bool LLBlockList::isActionEnabled(const LLSD& userdata)
 
 	const std::string command_name = userdata.asString();
 
-	if ("profile_item" == command_name)
+	if ("profile_item" == command_name 
+		|| "block_voice" == command_name
+		|| "block_text" == command_name
+		|| "block_particles" == command_name
+		|| "block_obj_sounds" == command_name)
 	{
 		LLBlockedListItem* item = getBlockedItem();
 		action_enabled = item && (LLMute::AGENT == item->getType());
@@ -314,6 +320,78 @@ void LLBlockList::onCustomAction(const LLSD& userdata)
 			break;
 		}
 	}
+	else if ("block_voice" == command_name)
+	{
+		toggleMute(LLMute::flagVoiceChat);
+	}
+	else if ("block_text" == command_name)
+	{
+		toggleMute(LLMute::flagTextChat);
+	}
+	else if ("block_particles" == command_name)
+	{
+		toggleMute(LLMute::flagParticles);
+	}
+	else if ("block_obj_sounds" == command_name)
+	{
+		toggleMute(LLMute::flagObjectSounds);
+	}
+}
+
+bool LLBlockList::isMenuItemChecked(const LLSD& userdata)
+{
+	LLBlockedListItem* item = getBlockedItem();
+	const std::string command_name = userdata.asString();
+
+	if ("block_voice" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagVoiceChat);
+	}
+	else if ("block_text" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagTextChat);
+	}
+	else if ("block_particles" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagParticles);
+	}
+	else if ("block_obj_sounds" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagObjectSounds);
+	}
+
+	return false;
+}
+
+bool LLBlockList::isMenuItemVisible(const LLSD& userdata)
+{
+	LLBlockedListItem* item = getBlockedItem();
+	const std::string command_name = userdata.asString();
+
+	if ("block_voice" == command_name
+		|| "block_text" == command_name
+		|| "block_particles" == command_name
+		|| "block_obj_sounds" == command_name)
+	{
+		return item && (LLMute::AGENT == item->getType());
+	}
+
+	return false;
+}
+
+void LLBlockList::toggleMute(U32 flags)
+{
+	LLBlockedListItem* item = getBlockedItem();
+	LLMute mute(item->getUUID(), item->getName(), item->getType());
+
+	if (!LLMuteList::getInstance()->isMuted(item->getUUID(), flags))
+	{
+		LLMuteList::getInstance()->add(mute, flags);
+	}
+	else
+	{
+		LLMuteList::getInstance()->remove(mute, flags);
+	}
 }
 
 bool LLBlockListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h
index 96af8d898e..ac0729c610 100644
--- a/indra/newview/llblocklist.h
+++ b/indra/newview/llblocklist.h
@@ -79,6 +79,9 @@ private:
 
 	bool isActionEnabled(const LLSD& userdata);
 	void onCustomAction (const LLSD& userdata);
+	bool isMenuItemChecked(const LLSD& userdata);
+	bool isMenuItemVisible(const LLSD& userdata);
+	void toggleMute(U32 flags);
 	void createList();
 
 	BlockListActionType getCurrentMuteListActionType();
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
index 63295ea27b..01ca38f51a 100644
--- a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
@@ -13,6 +13,80 @@
        function="Block.Enable"
        parameter="unblock_item" /> 
   </menu_item_call>
+
+  <menu_item_check
+   label="Block Voice"
+   layout="topleft"
+   name="BlockVoice">
+      <on_check
+       function="Block.Check"
+       parameter="block_voice" />
+      <on_click
+       function="Block.Action"
+       parameter="block_voice" />
+      <on_enable
+       function="Block.Enable"
+       parameter="block_voice" />
+      <on_visible
+       function="Block.Visible"
+       parameter="block_voice" />
+  </menu_item_check>
+
+  <menu_item_check
+   label="Block Text"
+   layout="topleft"
+   name="MuteText">
+      <on_check
+       function="Block.Check"
+       parameter="block_text" />
+      <on_click
+       function="Block.Action"
+       parameter="block_text" />
+     <on_enable
+       function="Block.Enable"
+       parameter="block_text" />
+     <on_visible
+       function="Block.Visible"
+       parameter="block_text" />
+  </menu_item_check>
+
+  <menu_item_check
+   label="Block Particles"
+   layout="topleft"
+   name="MuteText">
+      <on_check
+       function="Block.Check"
+       parameter="block_particles" />
+      <on_click
+       function="Block.Action" 
+       parameter="block_particles" />
+      <on_enable
+       function="Block.Enable"
+       parameter="block_particles" />
+      <on_visible
+       function="Block.Visible"
+       parameter="block_particles" />
+  </menu_item_check>
+
+  <menu_item_check
+   label="Block Object Sounds"
+   layout="topleft"
+   name="BlockObjectSounds">
+      <on_check
+       function="Block.Check"
+       parameter="block_obj_sounds" />
+      <on_click
+       function="Block.Action"
+       parameter="block_obj_sounds" />
+      <on_enable
+       function="Block.Enable"
+       parameter="block_obj_sounds" />
+      <on_visible
+       function="Block.Visible"
+       parameter="block_obj_sounds" />
+  </menu_item_check>
+
+  <menu_item_separator />
   <menu_item_call
    label="Profile..."
    name="profile">
-- 
cgit v1.2.3


From a1bc791bf8a6a7a837c8c9c29455fbef5d2e36f9 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 6 Mar 2017 18:02:26 +0200
Subject: MAINT-3683 "login failed" notice has an extra character in pop-up
 notification

---
 indra/newview/skins/default/xui/en/strings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 1d2c068e64..e3e770444c 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3883,9 +3883,9 @@ Abuse Report</string>
   <string name="words_separator" value=", "/>
 
   <string name="server_is_down">
-	Despite our best efforts, something unexpected has gone wrong.
+  Despite our best efforts, something unexpected has gone wrong.
 
-	Please check status.secondlifegrid.net to see if there is a known problem with the service.
+Please check status.secondlifegrid.net to see if there is a known problem with the service.
         If you continue to experience problems, please check your network and firewall setup.
   </string>
 
-- 
cgit v1.2.3


From 09869a13ee87a1373763a745103b8c530fa37f40 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Sat, 11 Mar 2017 20:46:56 +0200
Subject: MAINT-6789 bulk update can be resource hungry and needs to be
 monitored

---
 indra/newview/llinventorymodelbackgroundfetch.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 4a77edc565..a8919db828 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -360,9 +360,12 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching)
 	}
 }
 
+static LLTrace::BlockTimerStatHandle FTM_BULK_FETCH("Bulk Fetch");
+
 // Bundle up a bunch of requests to send all at once.
 void LLInventoryModelBackgroundFetch::bulkFetch()
 {
+	LL_RECORD_BLOCK_TIME(FTM_BULK_FETCH);
 	//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped.
 	//If there are items in mFetchQueue, we want to check the time since the last bulkFetch was 
 	//sent.  If it exceeds our retry time, go ahead and fire off another batch.  
-- 
cgit v1.2.3


From 84dd347ae782b5152fdb0fc3b964e88b1c9975c0 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 13 Mar 2017 20:48:44 +0200
Subject: MAINT-1324 Warning should appear that objects in different regions
 can't be linked

---
 indra/newview/llselectmgr.cpp                      | 35 ++++++++++++++++++++++
 indra/newview/llselectmgr.h                        |  3 ++
 .../newview/skins/default/xui/en/notifications.xml |  8 +++++
 3 files changed, 46 insertions(+)

diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 353c61da0c..983a7ca1ae 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -614,6 +614,12 @@ bool LLSelectMgr::linkObjects()
 		return true;
 	}
 
+	if (!LLSelectMgr::getInstance()->selectGetSameRegion())
+	{
+		LLNotificationsUtil::add("CannotLinkAcrossRegions");
+		return true;
+	}
+
 	LLSelectMgr::getInstance()->sendLink();
 
 	return true;
@@ -2778,6 +2784,35 @@ BOOL LLSelectMgr::selectGetRootsModify()
 	return TRUE;
 }
 
+//-----------------------------------------------------------------------------
+// selectGetSameRegion() - return TRUE if all objects are in same region
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetSameRegion()
+{
+    if (getSelection()->isEmpty())
+    {
+        return TRUE;
+    }
+    LLViewerObject* object = getSelection()->getFirstObject();
+    if (!object)
+    {
+        return FALSE;
+    }
+    LLViewerRegion* current_region = object->getRegion();
+
+    for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+        iter != getSelection()->root_end(); iter++)
+    {
+        LLSelectNode* node = *iter;
+        object = node->getObject();
+        if (!node->mValid || !object || current_region != object->getRegion())
+        {
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
 
 //-----------------------------------------------------------------------------
 // selectGetNonPermanentEnforced() - return TRUE if all objects are not
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 2a893af266..7ef0032645 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -624,6 +624,9 @@ public:
 	BOOL selectGetRootsModify();
 	BOOL selectGetModify();
 
+	// returns TRUE if all objects are in same region
+	BOOL selectGetSameRegion();
+
 	// returns TRUE if is all objects are non-permanent-enforced
 	BOOL selectGetRootsNonPermanentEnforced();
 	BOOL selectGetNonPermanentEnforced();
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a509adfcbc..bcdd182627 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1938,6 +1938,14 @@ Please make sure none are locked, and that you own all of them.
     <tag>fail</tag>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="CannotLinkAcrossRegions"
+   type="alertmodal">
+Objects cannot be linked across region boundaries.
+    <tag>fail</tag>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CannotLinkDifferentOwners"
-- 
cgit v1.2.3


From 2ed5487fa998ba79a98d8f4a6a8abbf60551c9e3 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 14 Mar 2017 18:20:49 +0200
Subject: MAINT-1800 Menu item appears at the top of the screen during
 teleporting

---
 indra/newview/llviewerwindow.cpp | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 61505b7c07..2d3b48bab3 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2724,8 +2724,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 			return TRUE;
 		}
 
-		if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
-			||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
+		if (gAgent.isInitialized()
+			&& (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
+			&& gMenuBarView
+			&& gMenuBarView->handleAcceleratorKey(key, mask))
+		{
+			LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+			return TRUE;
+		}
+
+		if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
 		{
 			LLViewerEventRecorder::instance().logKeyEvent(key,mask);
 			return TRUE;
@@ -2855,8 +2863,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	}
 
 	// give menus a chance to handle unmodified accelerator keys
-	if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
-		||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
+	if (gAgent.isInitialized()
+		&& (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
+		&& gMenuBarView
+		&& gMenuBarView->handleAcceleratorKey(key, mask))
+	{
+		LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+		return TRUE;
+	}
+
+	if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
 	{
 		return TRUE;
 	}
-- 
cgit v1.2.3


From 7d386378732fb19875e7fb0a3d969d0ba02dc7b3 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 15 Mar 2017 01:24:59 +0200
Subject: MAINT-7206 Fixed crash on doubleclick deselecting last mute type from
 the context menu

---
 indra/newview/llblocklist.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 08d6db4ceb..1589db15a5 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -341,6 +341,11 @@ void LLBlockList::onCustomAction(const LLSD& userdata)
 bool LLBlockList::isMenuItemChecked(const LLSD& userdata)
 {
 	LLBlockedListItem* item = getBlockedItem();
+	if (!item)
+	{
+		return false;
+	}
+
 	const std::string command_name = userdata.asString();
 
 	if ("block_voice" == command_name)
-- 
cgit v1.2.3


From d23b6e442e0a4d3a8badb51efd7611e23d138b26 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 15 Mar 2017 12:08:30 +0200
Subject: MAINT-7168 Avatar rendering settings adjustments

---
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/app_settings/settings.xml            |  11 +
 indra/newview/llfloateravatarrendersettings.cpp    | 235 +++++++++++++++++++++
 indra/newview/llfloateravatarrendersettings.h      |  67 ++++++
 indra/newview/llfloaterpreference.cpp              |  10 +-
 indra/newview/llfloaterpreference.h                |   1 +
 indra/newview/llmutelist.cpp                       |  96 +++++++++
 indra/newview/llmutelist.h                         |  20 ++
 indra/newview/llstartup.cpp                        |   2 +
 indra/newview/llviewerfloaterreg.cpp               |   2 +
 indra/newview/llvoavatar.cpp                       |  21 +-
 indra/newview/llvoavatar.h                         |   2 -
 .../xui/en/floater_avatar_render_settings.xml      |  55 +++++
 .../skins/default/xui/en/menu_attachment_other.xml |  25 ++-
 .../skins/default/xui/en/menu_avatar_other.xml     |  23 +-
 .../xui/en/menu_avatar_rendering_settings.xml      |  26 +++
 .../default/xui/en/panel_preferences_graphics1.xml |  62 ++++--
 17 files changed, 602 insertions(+), 58 deletions(-)
 create mode 100644 indra/newview/llfloateravatarrendersettings.cpp
 create mode 100644 indra/newview/llfloateravatarrendersettings.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index dbec4b5d65..7ed18801cf 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -203,6 +203,7 @@ set(viewer_SOURCE_FILES
     llfloaterautoreplacesettings.cpp
     llfloateravatar.cpp
     llfloateravatarpicker.cpp
+    llfloateravatarrendersettings.cpp
     llfloateravatartextures.cpp
     llfloaterbeacons.cpp
     llfloaterbigpreview.cpp
@@ -820,6 +821,7 @@ set(viewer_HEADER_FILES
     llfloaterautoreplacesettings.h
     llfloateravatar.h
     llfloateravatarpicker.h
+    llfloateravatarrendersettings.h
     llfloateravatartextures.h
     llfloaterbeacons.h
     llfloaterbigpreview.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index fb644d3d5a..097a9ac7b9 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8426,6 +8426,17 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
+  <key>AlwaysRenderFriends</key>
+    <map>
+      <key>Comment</key>
+      <string>Always render friends regardless of max complexity</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
   <key>RenderAvatar</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
new file mode 100644
index 0000000000..530b3bd481
--- /dev/null
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -0,0 +1,235 @@
+/**
+ * @file llfloateravatarrendersettings.cpp
+ * @brief Shows the list of avatars with non-default rendering settings
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloateravatarrendersettings.h"
+
+#include "llavatarnamecache.h"
+#include "llfiltereditor.h"
+#include "llfloaterreg.h"
+#include "llnamelistctrl.h"
+#include "llmenugl.h"
+#include "llviewerobjectlist.h"
+#include "llvoavatar.h"
+
+class LLSettingsContextMenu : public LLListContextMenu
+
+{
+public:
+    LLSettingsContextMenu(LLFloaterAvatarRenderSettings* floater_settings)
+        :   mFloaterSettings(floater_settings)
+    {}
+protected:
+    LLContextMenu* createMenu()
+    {
+        LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+        LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+        registrar.add("Settings.SetRendering", boost::bind(&LLFloaterAvatarRenderSettings::onCustomAction, mFloaterSettings, _2, mUUIDs.front()));
+        enable_registrar.add("Settings.IsSelected", boost::bind(&LLFloaterAvatarRenderSettings::isActionChecked, mFloaterSettings, _2, mUUIDs.front()));
+        LLContextMenu* menu = createFromFile("menu_avatar_rendering_settings.xml");
+
+        return menu;
+    }
+
+    LLFloaterAvatarRenderSettings* mFloaterSettings;
+};
+
+class LLAvatarRenderMuteListObserver : public LLMuteListObserver
+{
+    /* virtual */ void onChange()  { LLFloaterAvatarRenderSettings::setNeedsUpdate();}
+};
+
+static LLAvatarRenderMuteListObserver sAvatarRenderMuteListObserver;
+
+LLFloaterAvatarRenderSettings::LLFloaterAvatarRenderSettings(const LLSD& key)
+:   LLFloater(key),
+	mAvatarSettingsList(NULL),
+	mNeedsUpdate(false)
+{
+    mContextMenu = new LLSettingsContextMenu(this);
+    LLRenderMuteList::getInstance()->addObserver(&sAvatarRenderMuteListObserver);
+}
+
+LLFloaterAvatarRenderSettings::~LLFloaterAvatarRenderSettings()
+{
+    delete mContextMenu;
+    LLRenderMuteList::getInstance()->removeObserver(&sAvatarRenderMuteListObserver);
+}
+
+BOOL LLFloaterAvatarRenderSettings::postBuild()
+{
+    LLFloater::postBuild();
+    mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
+    mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
+
+    getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
+
+	return TRUE;
+}
+
+void LLFloaterAvatarRenderSettings::draw()
+{
+    if(mNeedsUpdate)
+    {
+        updateList();
+        mNeedsUpdate = false;
+    }
+
+    LLFloater::draw();
+}
+
+void LLFloaterAvatarRenderSettings::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
+{
+    LLNameListCtrl* list = dynamic_cast<LLNameListCtrl*>(ctrl);
+    if (!list) return;
+    list->selectItemAt(x, y, MASK_NONE);
+    uuid_vec_t selected_uuids;
+
+    if(list->getCurrentID().notNull())
+    {
+        selected_uuids.push_back(list->getCurrentID());
+        mContextMenu->show(ctrl, selected_uuids, x, y);
+    }
+}
+
+void LLFloaterAvatarRenderSettings::onOpen(const LLSD& key)
+{
+    updateList();
+}
+
+void LLFloaterAvatarRenderSettings::updateList()
+{
+    mAvatarSettingsList->deleteAllItems();
+    LLAvatarName av_name;
+    LLNameListCtrl::NameItem item_params;
+    for (std::map<LLUUID, S32>::iterator iter = LLRenderMuteList::getInstance()->sVisuallyMuteSettingsMap.begin(); iter != LLRenderMuteList::getInstance()->sVisuallyMuteSettingsMap.end(); iter++)
+    {
+        item_params.value = iter->first;
+        LLAvatarNameCache::get(iter->first, &av_name);
+        if(!isHiddenRow(av_name.getCompleteName()))
+        {
+            item_params.columns.add().value(av_name.getCompleteName()).column("name");
+            std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
+            item_params.columns.add().value(setting).column("setting");
+            mAvatarSettingsList->addNameItemRow(item_params);
+        }
+    }
+}
+
+void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string)
+{
+    std::string filter_upper = search_string;
+    LLStringUtil::toUpper(filter_upper);
+    if (mNameFilter != filter_upper)
+    {
+        mNameFilter = filter_upper;
+        mNeedsUpdate = true;
+    }
+}
+
+bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name)
+{
+    if (mNameFilter.empty()) return false;
+    std::string upper_name = av_name;
+    LLStringUtil::toUpper(upper_name);
+    return std::string::npos == upper_name.find(mNameFilter);
+}
+
+static LLVOAvatar* find_avatar(const LLUUID& id)
+{
+    LLViewerObject *obj = gObjectList.findObject(id);
+    while (obj && obj->isAttachment())
+    {
+        obj = (LLViewerObject *)obj->getParent();
+    }
+
+    if (obj && obj->isAvatar())
+    {
+        return (LLVOAvatar*)obj;
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+
+void LLFloaterAvatarRenderSettings::onCustomAction (const LLSD& userdata, const LLUUID& av_id)
+{
+    const std::string command_name = userdata.asString();
+
+    S32 new_setting = 0;
+    if ("default" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY);
+	}
+    else if ("never" == command_name)
+	{
+        new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
+    }
+    else if ("always" == command_name)
+	{
+        new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
+	}
+
+    LLVOAvatar *avatarp = find_avatar(av_id);
+    if (avatarp)
+    {
+        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
+    }
+    else
+    {
+        LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
+    }
+}
+
+
+bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const LLUUID& av_id)
+{
+    const std::string command_name = userdata.asString();
+
+    S32 visual_setting = LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(av_id);
+    if ("default" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
+    }
+    else if ("never" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));
+    }
+    else if ("always" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_ALWAYS_RENDER));
+    }
+    return false;
+}
+
+void LLFloaterAvatarRenderSettings::setNeedsUpdate()
+{
+    LLFloaterAvatarRenderSettings* instance = LLFloaterReg::getTypedInstance<LLFloaterAvatarRenderSettings>("avatar_render_settings");
+    if(!instance) return;
+    instance->mNeedsUpdate = true;
+}
diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h
new file mode 100644
index 0000000000..367b0620ac
--- /dev/null
+++ b/indra/newview/llfloateravatarrendersettings.h
@@ -0,0 +1,67 @@
+/**
+ * @file llfloateravatarrendersettings.h
+ * @brief Shows the list of avatars with non-default rendering settings
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERAVATARRENDERSETTINGS_H
+#define LL_LLFLOATERAVATARRENDERSETTINGS_H
+
+#include "llfloater.h"
+#include "lllistcontextmenu.h"
+#include "llmutelist.h"
+
+class LLNameListCtrl;
+
+class LLFloaterAvatarRenderSettings : public LLFloater
+{
+public:
+
+    LLFloaterAvatarRenderSettings(const LLSD& key);
+    virtual ~LLFloaterAvatarRenderSettings();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& key);
+    /*virtual*/ void draw();
+
+    void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+
+    void updateList();
+    void onFilterEdit(const std::string& search_string);
+    void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
+    bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
+
+    static void setNeedsUpdate();
+
+private:
+    bool isHiddenRow(const std::string& av_name);
+
+    bool mNeedsUpdate;
+    LLListContextMenu* mContextMenu;
+    LLNameListCtrl* mAvatarSettingsList;
+
+    std::string mNameFilter;
+};
+
+
+#endif //LL_LLFLOATERAVATARRENDERSETTINGS_H
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index df4bc043e5..1f460c05ec 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -360,6 +360,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
+	mCommitCallbackRegistrar.add("Pref.RenderExceptions",       boost::bind(&LLFloaterPreference::onClickRenderExceptions, this));
 	mCommitCallbackRegistrar.add("Pref.HardwareDefaults",		boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
 	mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable",	boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
 	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",	boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
@@ -385,7 +386,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
-	
+
 	gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged,  _2));
 
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
@@ -786,10 +787,12 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
 	LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
 	LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
+	LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
 
 	load_btn->setEnabled(started);
 	save_btn->setEnabled(started);
 	delete_btn->setEnabled(started);
+	exceptions_btn->setEnabled(started);
 }
 
 void LLFloaterPreference::onVertexShaderEnable()
@@ -2075,6 +2078,11 @@ void LLFloaterPreference::onClickSpellChecker()
     LLFloaterReg::showInstance("prefs_spellchecker");
 }
 
+void LLFloaterPreference::onClickRenderExceptions()
+{
+    LLFloaterReg::showInstance("avatar_render_settings");
+}
+
 void LLFloaterPreference::onClickAdvanced()
 {
 	LLFloaterReg::showInstance("prefs_graphics_advanced");
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index ea199cf034..2bb2e7e9ff 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -171,6 +171,7 @@ public:
 	void onClickPermsDefault();
 	void onClickAutoReplace();
 	void onClickSpellChecker();
+	void onClickRenderExceptions();
 	void onClickAdvanced();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 3af9c2f912..02b28a2bf8 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -812,3 +812,99 @@ void LLMuteList::notifyObserversDetailed(const LLMute& mute)
 		it = mObservers.upper_bound(observer);
 	}
 }
+
+LLRenderMuteList::LLRenderMuteList()
+{}
+
+bool LLRenderMuteList::saveToFile()
+{
+    std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
+    LLFILE* fp = LLFile::fopen(filename, "wb");
+    if (!fp)
+    {
+        LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
+        return false;
+    }
+    for (std::map<LLUUID, S32>::iterator it = sVisuallyMuteSettingsMap.begin(); it != sVisuallyMuteSettingsMap.end(); ++it)
+    {
+        if (it->second != 0)
+        {
+            std::string id_string;
+            it->first.toString(id_string);
+            fprintf(fp, "%d %s\n", (S32)it->second, id_string.c_str());
+        }
+    }
+    fclose(fp);
+    return true;
+}
+
+bool LLRenderMuteList::loadFromFile()
+{
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
+	LLFILE* fp = LLFile::fopen(filename, "rb");
+	if (!fp)
+	{
+		LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
+		return false;
+	}
+
+	char id_buffer[MAX_STRING];
+	char buffer[MAX_STRING];
+	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+	{
+		id_buffer[0] = '\0';
+		S32 setting = 0;
+		sscanf(buffer, " %d %254s\n", &setting, id_buffer);
+		sVisuallyMuteSettingsMap[LLUUID(id_buffer)] = setting;
+	}
+	fclose(fp);
+    return true;
+}
+
+void LLRenderMuteList::saveVisualMuteSetting(const LLUUID& agent_id, S32 setting)
+{
+    if(setting == 0)
+    {
+        sVisuallyMuteSettingsMap.erase(agent_id);
+    }
+    else
+    {
+        sVisuallyMuteSettingsMap[agent_id] = setting;
+    }
+    saveToFile();
+    notifyObservers();
+}
+
+S32 LLRenderMuteList::getSavedVisualMuteSetting(const LLUUID& agent_id)
+{
+    std::map<LLUUID, S32>::iterator iter = sVisuallyMuteSettingsMap.find(agent_id);
+    if (iter != sVisuallyMuteSettingsMap.end())
+    {
+        return iter->second;
+    }
+
+    return 0;
+}
+
+void LLRenderMuteList::addObserver(LLMuteListObserver* observer)
+{
+    mObservers.insert(observer);
+}
+
+void LLRenderMuteList::removeObserver(LLMuteListObserver* observer)
+{
+    mObservers.erase(observer);
+}
+
+void LLRenderMuteList::notifyObservers()
+{
+    for (observer_set_t::iterator it = mObservers.begin();
+        it != mObservers.end();
+        )
+    {
+        LLMuteListObserver* observer = *it;
+        observer->onChange();
+        // In case onChange() deleted an entry.
+        it = mObservers.upper_bound(observer);
+    }
+}
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 4ceddc97fd..9ab978353b 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -175,5 +175,25 @@ public:
 	virtual void onChangeDetailed(const LLMute& ) { }
 };
 
+class LLRenderMuteList : public LLSingleton<LLRenderMuteList>
+{
+    LLSINGLETON(LLRenderMuteList);
+public:
+	bool loadFromFile();
+	bool saveToFile();
+	S32 getSavedVisualMuteSetting(const LLUUID& agent_id);
+	void saveVisualMuteSetting(const LLUUID& agent_id, S32 setting);
+
+	void addObserver(LLMuteListObserver* observer);
+	void removeObserver(LLMuteListObserver* observer);
+
+	std::map<LLUUID, S32> sVisuallyMuteSettingsMap;
+
+private:
+	void notifyObservers();
+	typedef std::set<LLMuteListObserver*> observer_set_t;
+	observer_set_t mObservers;
+};
+
 
 #endif //LL_MUTELIST_H
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 347409fcab..0a85344025 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -967,6 +967,8 @@ bool idle_startup()
 		// Load media plugin cookies
 		LLViewerMedia::loadCookieFile();
 
+		LLRenderMuteList::getInstance()->loadFromFile();
+
 		//-------------------------------------------------
 		// Handle startup progress screen
 		//-------------------------------------------------
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 46525e8455..cf18299b0b 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -38,6 +38,7 @@
 #include "llfloaterautoreplacesettings.h"
 #include "llfloateravatar.h"
 #include "llfloateravatarpicker.h"
+#include "llfloateravatarrendersettings.h"
 #include "llfloateravatartextures.h"
 #include "llfloaterbigpreview.h"
 #include "llfloaterbeacons.h"
@@ -194,6 +195,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
 	LLFloaterReg::add("avatar", "floater_avatar.xml",  (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>);
 	LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
+	LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>);
 	LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarTextures>);
 
 	LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBeacons>);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 760eee17f3..f6a16f7da1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -728,7 +728,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	    LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
 	}
 
-	mVisuallyMuteSetting = getSavedVisualMuteSettings();
+	mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID()));
 }
 
 std::string LLVOAvatar::avString() const
@@ -7076,7 +7076,9 @@ BOOL LLVOAvatar::isFullyLoaded() const
 bool LLVOAvatar::isTooComplex() const
 {
 	bool too_complex;
-	if (isSelf() || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+	bool render_friend =  (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends"));
+
+	if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
 	{
 		too_complex = false;
 	}
@@ -9230,25 +9232,12 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
     }
 }
 
-//static
-std::map<LLUUID, LLVOAvatar::VisualMuteSettings> LLVOAvatar::sVisuallyMuteSettingsMap;
-
 void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
 {
     mVisuallyMuteSetting = set;
     mNeedsImpostorUpdate = TRUE;
-    sVisuallyMuteSettingsMap[getID()] = set;
-}
-
-LLVOAvatar::VisualMuteSettings LLVOAvatar::getSavedVisualMuteSettings()
-{
-    std::map<LLUUID, VisualMuteSettings>::iterator iter = sVisuallyMuteSettingsMap.find(getID());
-    if (iter != sVisuallyMuteSettingsMap.end())
-    {
-        return iter->second;
-    }
 
-    return AV_RENDER_NORMALLY;
+    LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));
 }
 
 void LLVOAvatar::calcMutedAVColor()
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 73e4fbd108..bd89d4ef23 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -407,7 +407,6 @@ public:
 	};
 	void		setVisualMuteSettings(VisualMuteSettings set);
 	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	};
-	VisualMuteSettings  getSavedVisualMuteSettings();
 
 	U32 		renderRigid();
 	U32 		renderSkinned();
@@ -441,7 +440,6 @@ public:
 
 	VisualMuteSettings		mVisuallyMuteSetting;			// Always or never visually mute this AV
 
-	static std::map<LLUUID, VisualMuteSettings> sVisuallyMuteSettingsMap;
 	//--------------------------------------------------------------------
 	// Morph masks
 	//--------------------------------------------------------------------
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
new file mode 100644
index 0000000000..dd37e329e5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ positioning="cascading"
+ height="200"
+ min_height="100"
+ min_width="230"
+ layout="topleft"
+ name="floater_avatar_render_settings"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="AVATAR RENDER SETTINGS"
+ width="300">
+    <string
+     name="av_never_render"
+     value="Never"/>
+    <string
+     name="av_always_render"
+     value="Always"/>
+    <filter_editor
+     follows="left|top|right"
+     height="23"
+     layout="topleft"
+     left="8"
+     right="-8"
+     label="Filter People"
+     max_length_chars="300"
+     name="people_filter_input"
+     text_color="Black"
+     text_pad_left="10"
+     top="4" />
+    <name_list
+     allow_select="true"
+     bottom="-8"
+     draw_heading="true"
+     opaque="true"
+     follows="all"
+     left="8"
+     keep_selection_visible_on_reshape="true"
+     item_pad="2"
+     multi_select="false"
+     name="render_settings_list"
+     right="-8"
+     top="32">
+        <name_list.columns
+         label="Name"
+         name="name"
+         relative_width="0.65" />
+        <name_list.columns
+         label="Render setting"
+         name="setting"
+         relative_width="0.35" />
+     </name_list>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 2f60bab0b7..49b9ac273d 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -130,10 +130,13 @@
    </menu_item_call>
 
    <menu_item_separator />
-    
+      <context_menu
+       label="Render Avatar"
+       layout="topleft"
+        name="Render Avatar">
       <menu_item_check
         name="RenderNormally"
-        label="Render Normally">
+        label="Default">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
           parameter="0" />
@@ -142,26 +145,26 @@
 	      parameter="0" />
       </menu_item_check>
       <menu_item_check
-        name="DoNotRender"
-        label="Do Not Render">
+        name="AlwaysRenderFully"
+        label="Always">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="1" />
+          parameter="2" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="1" />
+	      parameter="2" />
       </menu_item_check>
       <menu_item_check
-        name="AlwaysRenderFully"
-        label="Render Fully">
+        name="DoNotRender"
+        label="Never">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="2" />
+          parameter="1" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="2" />
+	      parameter="1" />
       </menu_item_check>
-
+      </context_menu>
   <menu_item_separator
        layout="topleft" name="Impostor seperator"/>
 
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index ddfff23410..c5426cb232 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -121,9 +121,13 @@
 
    <menu_item_separator />
     
+ <context_menu
+       label="Render Avatar"
+       layout="topleft"
+        name="Render Avatar">
       <menu_item_check
         name="RenderNormally"
-        label="Render Normally">
+        label="Default">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
           parameter="0" />
@@ -132,25 +136,26 @@
 	      parameter="0" />
       </menu_item_check>
       <menu_item_check
-        name="DoNotRender"
-        label="Do Not Render">
+        name="AlwaysRenderFully"
+        label="Always">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="1" />
+          parameter="2" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="1" />
+	      parameter="2" />
       </menu_item_check>
       <menu_item_check
-        name="AlwaysRenderFully"
-        label="Render Fully">
+        name="DoNotRender"
+        label="Never">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="2" />
+          parameter="1" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="2" />
+	      parameter="1" />
       </menu_item_check>
+      </context_menu>
 
   <menu_item_separator 
     layout="topleft"  name="Impostor seperator"/>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
new file mode 100644
index 0000000000..5163cd3115
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Settings">
+    <menu_item_check
+     label="Default"
+     layout="topleft"
+     name="default">
+        <on_click function="Settings.SetRendering" parameter="default"/>
+	<on_check function="Settings.IsSelected" parameter="default" />  
+    </menu_item_check>
+    <menu_item_check
+     label="Always render"
+     layout="topleft"
+     name="always_render">
+        <on_click function="Settings.SetRendering" parameter="always"/>
+	<on_check function="Settings.IsSelected" parameter="always" />  
+    </menu_item_check>
+    <menu_item_check
+     label="Never render"
+     layout="topleft"
+     name="never_render">
+        <on_click function="Settings.SetRendering" parameter="never"/>
+	<on_check function="Settings.IsSelected" parameter="never" />  
+    </menu_item_check>  
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 32cbbff8b7..652b7fd029 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -231,6 +231,34 @@
      m
   </text>
 
+  <check_box
+    control_name="WindLightUseAtmosShaders"
+    height="16"
+    initial_value="true"
+    label="Atmospheric shaders"
+    layout="topleft"
+    left="30"
+    name="WindLightUseAtmosShaders"
+    top_delta="24"
+    width="280">
+    <check_box.commit_callback
+      function="Pref.VertexShaderEnable" />
+  </check_box>
+
+  <check_box
+    control_name="RenderDeferred"
+    height="16"
+    initial_value="true"
+    label="Advanced Lighting Model"
+    layout="topleft"
+    left="30"
+    name="UseLightShaders"
+    top_delta="24"
+    width="256">
+    <check_box.commit_callback
+      function="Pref.VertexShaderEnable" />
+  </check_box>
+  
   <slider
     control_name="IndirectMaxComplexity"
     tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
@@ -246,7 +274,7 @@
     max_val="101"
     name="IndirectMaxComplexity"
     show_text="false"
-    top_delta="24"
+    top_delta="60"
     width="300">
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxComplexity"
@@ -265,34 +293,30 @@
     width="65">
        0
   </text>
-
   <check_box
-    control_name="WindLightUseAtmosShaders"
+    control_name="AlwaysRenderFriends"
     height="16"
     initial_value="true"
-    label="Atmospheric shaders"
+    label="Always Render Friends"
     layout="topleft"
     left="30"
-    name="WindLightUseAtmosShaders"
+    name="AlwaysRenderFriends"
     top_delta="24"
-    width="280">
+    width="256">
     <check_box.commit_callback
-      function="Pref.VertexShaderEnable" />
+      function="Pref.RenderFriends" />
   </check_box>
-
-  <check_box
-    control_name="RenderDeferred"
-    height="16"
-    initial_value="true"
-    label="Advanced Lighting Model"
+  <button
+    height="23"
+    label="Exceptions..."
     layout="topleft"
-    left="30"
-    name="UseLightShaders"
+    left="48"
+    name="RenderExceptionsButton"
     top_delta="24"
-    width="256">
-    <check_box.commit_callback
-      function="Pref.VertexShaderEnable" />
-  </check_box>
+    width="100">
+    <button.commit_callback
+      function="Pref.RenderExceptions"/>
+  </button>
 
 <!-- End of Basic Settings block -->
 
-- 
cgit v1.2.3


From 26d81d3d6cc56f8f8df9f33ff27229671fb8a2db Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 15 Mar 2017 16:01:39 +0200
Subject: MAINT-7199 Field "From" on the tab "Send via E-mail" should be
 initialized to the agent full name

---
 indra/newview/llpanelsnapshotpostcard.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index ebf9153da9..3d18e837af 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -106,6 +106,14 @@ BOOL LLPanelSnapshotPostcard::postBuild()
 // virtual
 void LLPanelSnapshotPostcard::onOpen(const LLSD& key)
 {
+	LLUICtrl* name_form = getChild<LLUICtrl>("name_form");
+	if (name_form && name_form->getValue().asString().empty())
+	{
+		std::string name_string;
+		LLAgentUI::buildFullname(name_string);
+		getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
+	}
+
 	LLPanelSnapshot::onOpen(key);
 }
 
-- 
cgit v1.2.3


From bc268526b742068027da960c53815b7891bf45c7 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 16 Mar 2017 17:34:47 +0200
Subject: MAINT-7208 Some messages had links that were not highlighted

---
 indra/newview/skins/default/xui/en/floater_tos.xml | 2 +-
 indra/newview/skins/default/xui/en/strings.xml     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index 590d9d1844..612c894b59 100644
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -70,7 +70,7 @@
      top="32"
      word_wrap="true"
      width="552">
-       You will need to go to my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you!
+       You will need to go to https://my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you!
      </text>
     <web_browser
       trusted_content="true" 
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e3e770444c..5f686a87be 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3885,7 +3885,7 @@ Abuse Report</string>
   <string name="server_is_down">
   Despite our best efforts, something unexpected has gone wrong.
 
-Please check status.secondlifegrid.net to see if there is a known problem with the service.
+Please check http://status.secondlifegrid.net to see if there is a known problem with the service.
         If you continue to experience problems, please check your network and firewall setup.
   </string>
 
-- 
cgit v1.2.3


From 3c637e49452229e8df3cce833a275daaef650d9c Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 17 Mar 2017 10:18:31 +0200
Subject: MAINT-7215 Add "+" button next to filter editor in Avatar rendering
 settings floater

---
 indra/newview/llfloateravatarrendersettings.cpp    | 61 ++++++++++++++++++++--
 indra/newview/llfloateravatarrendersettings.h      |  4 ++
 .../xui/en/floater_avatar_render_settings.xml      | 21 ++++++--
 .../xui/en/menu_avatar_rendering_settings_add.xml  | 18 +++++++
 .../default/xui/en/panel_preferences_graphics1.xml |  2 -
 5 files changed, 94 insertions(+), 12 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml

diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
index 530b3bd481..e7ac3f2737 100644
--- a/indra/newview/llfloateravatarrendersettings.cpp
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -28,6 +28,7 @@
 #include "llfloateravatarrendersettings.h"
 
 #include "llavatarnamecache.h"
+#include "llfloateravatarpicker.h"
 #include "llfiltereditor.h"
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
@@ -71,6 +72,7 @@ LLFloaterAvatarRenderSettings::LLFloaterAvatarRenderSettings(const LLSD& key)
 {
     mContextMenu = new LLSettingsContextMenu(this);
     LLRenderMuteList::getInstance()->addObserver(&sAvatarRenderMuteListObserver);
+    mCommitCallbackRegistrar.add("Settings.AddNewEntry", boost::bind(&LLFloaterAvatarRenderSettings::onClickAdd, this, _2));
 }
 
 LLFloaterAvatarRenderSettings::~LLFloaterAvatarRenderSettings()
@@ -84,12 +86,20 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()
     LLFloater::postBuild();
     mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
     mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
-
+    this->setVisibleCallback(boost::bind(&LLFloaterAvatarRenderSettings::removePicker, this));
     getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
 
 	return TRUE;
 }
 
+void LLFloaterAvatarRenderSettings::removePicker()
+{
+    if(mPicker.get())
+    {
+        mPicker.get()->closeFloater();
+    }
+}
+
 void LLFloaterAvatarRenderSettings::draw()
 {
     if(mNeedsUpdate)
@@ -185,15 +195,15 @@ void LLFloaterAvatarRenderSettings::onCustomAction (const LLSD& userdata, const
     if ("default" == command_name)
     {
         new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY);
-	}
+    }
     else if ("never" == command_name)
-	{
+    {
         new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
     }
     else if ("always" == command_name)
-	{
+    {
         new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
-	}
+    }
 
     LLVOAvatar *avatarp = find_avatar(av_id);
     if (avatarp)
@@ -233,3 +243,44 @@ void LLFloaterAvatarRenderSettings::setNeedsUpdate()
     if(!instance) return;
     instance->mNeedsUpdate = true;
 }
+
+void LLFloaterAvatarRenderSettings::onClickAdd(const LLSD& userdata)
+{
+    const std::string command_name = userdata.asString();
+    S32 visual_setting = 0;
+    if ("never" == command_name)
+    {
+        visual_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
+    }
+    else if ("always" == command_name)
+    {
+        visual_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
+    }
+
+    LLView * button = findChild<LLButton>("plus_btn", TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+    LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterAvatarRenderSettings::callbackAvatarPicked, this, _1, visual_setting),
+                                                                    FALSE, TRUE, FALSE, root_floater->getName(), button);
+
+    if (root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+
+    mPicker = picker->getHandle();
+}
+
+void LLFloaterAvatarRenderSettings::callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting)
+{
+    if (ids.empty()) return;
+
+    LLVOAvatar *avatarp = find_avatar(ids[0]);
+    if (avatarp)
+    {
+        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(visual_setting));
+    }
+    else
+    {
+        LLRenderMuteList::getInstance()->saveVisualMuteSetting(ids[0], visual_setting);
+    }
+}
diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h
index 367b0620ac..fe727bcf32 100644
--- a/indra/newview/llfloateravatarrendersettings.h
+++ b/indra/newview/llfloateravatarrendersettings.h
@@ -50,15 +50,19 @@ public:
     void onFilterEdit(const std::string& search_string);
     void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
     bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
+    void onClickAdd(const LLSD& userdata);
 
     static void setNeedsUpdate();
 
 private:
     bool isHiddenRow(const std::string& av_name);
+    void callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting);
+    void removePicker();
 
     bool mNeedsUpdate;
     LLListContextMenu* mContextMenu;
     LLNameListCtrl* mAvatarSettingsList;
+    LLHandle<LLFloater> mPicker;
 
     std::string mNameFilter;
 };
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
index dd37e329e5..03e812d36d 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
@@ -23,22 +23,33 @@
      height="23"
      layout="topleft"
      left="8"
-     right="-8"
+     right="-47"
      label="Filter People"
      max_length_chars="300"
      name="people_filter_input"
      text_color="Black"
      text_pad_left="10"
      top="4" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="AddItem_Off"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="7"
+     menu_filename="menu_avatar_rendering_settings_add.xml"
+     menu_position="bottomleft"
+     name="plus_btn"
+     tool_tip="Actions on selected person"
+     top="3"
+     width="31" />
     <name_list
-     allow_select="true"
      bottom="-8"
      draw_heading="true"
-     opaque="true"
      follows="all"
      left="8"
-     keep_selection_visible_on_reshape="true"
-     item_pad="2"
      multi_select="false"
      name="render_settings_list"
      right="-8"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
new file mode 100644
index 0000000000..c64b24ed70
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_settings_add.xml"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Always Render a Resident..."
+   name="add_avatar_always_render">
+      <on_click
+       function="Settings.AddNewEntry" parameter="always"/>
+  </menu_item_call>
+  <menu_item_call
+   label="Never Render a Resident..."
+   name="add_avatar_never_render">
+      <on_click
+       function="Settings.AddNewEntry"  parameter="never"/>
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 652b7fd029..4692a226d9 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -303,8 +303,6 @@
     name="AlwaysRenderFriends"
     top_delta="24"
     width="256">
-    <check_box.commit_callback
-      function="Pref.RenderFriends" />
   </check_box>
   <button
     height="23"
-- 
cgit v1.2.3


From 1132b33028b056fce6474879e06b077c6f9cb50e Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 16 Mar 2017 19:23:26 +0200
Subject: MAINT-1858 Fixed camera not looking at avatar if "Editing Appearance"
 while moving

---
 indra/newview/llagentcamera.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index e335eabd1a..7723dbf978 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1537,6 +1537,11 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 	}
 	else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
+		LLVector3 focus_target = isAgentAvatarValid()
+			? gAgentAvatarp->mHeadp->getWorldPosition()
+			: gAgent.getPositionAgent();
+		LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
+		mFocusTargetGlobal = focus_target_global;
 		return mFocusTargetGlobal;
 	}
 	else if (!mFocusOnAvatar)
-- 
cgit v1.2.3


From 459d5c6c32ccc83de5bc6da0812aaa9d4f788052 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 20 Mar 2017 11:09:11 +0200
Subject: MAINT-7117 Don't Show "Unknown error" in warning dialog

---
 indra/newview/llmarketplacefunctions.cpp             | 11 ++++++++++-
 indra/newview/skins/default/xui/en/notifications.xml |  3 +--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 54f95520db..a0e19f2d19 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -121,7 +121,6 @@ namespace {
         {
             // Prompt the user with the warning (so they know why things are failing)
             LLSD subs;
-            subs["[ERROR_REASON]"] = reason;
             // We do show long descriptions in the alert (unlikely to be readable). The description string will be in the log though.
             std::string description;
             if (result.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT))
@@ -145,6 +144,16 @@ namespace {
             {
                 description = result.asString();
             }
+            std::string reason_lc = reason;
+            LLStringUtil::toLower(reason_lc);
+            if (!description.empty() && reason_lc.find("unknown") != std::string::npos)
+            {
+                subs["[ERROR_REASON]"] = "";
+            }
+            else
+            {
+                subs["[ERROR_REASON]"] = "'" + reason +"'\n";
+            }
             subs["[ERROR_DESCRIPTION]"] = description;
             LLNotificationsUtil::add("MerchantTransactionFailed", subs);
         }
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index bcdd182627..3fcd91f89b 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -341,8 +341,7 @@ Initialization with the Marketplace failed because of a system or network error.
         type="alertmodal">
         The transaction with the Marketplace failed with the following error :
         
-        Reason : &apos;[ERROR_REASON]&apos;
-        [ERROR_DESCRIPTION]
+        [ERROR_REASON][ERROR_DESCRIPTION]
         
         <usetemplate
         name="okbutton"
-- 
cgit v1.2.3


From 10a3eb049ceb1d0c83d6a79a367448a98a354206 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 20 Mar 2017 16:58:25 +0200
Subject: MAINT-7223 Odd placement on box in chat preferences

---
 .../skins/default/xui/en/panel_preferences_chat.xml    | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 8d55e311f6..440c6613d5 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -432,18 +432,16 @@
         top_pad="6"
         name="inventory_offer"
         width="150" />
-
+    <view_border
+        bevel_style="none"
+        height="0"
+        layout="topleft"
+        left="0"
+        name="cost_text_border"
+        top_pad="7"
+        width="492"/>
   </panel>
 
-  <view_border
-      bevel_style="none"
-      height="0"
-      layout="topleft"
-      left="13"
-      name="cost_text_border"
-      top_pad="5"
-      width="495"/>
-
   <panel
       height="50"
       layout="topleft"
-- 
cgit v1.2.3


From 4261f6ee117e361d3c43147d5f02d7607c63b2ff Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 22 Mar 2017 17:50:04 +0200
Subject: MAINT-6404 FIXED When pasting from Mac Word into a notecard, line
 break is replaced by ?

---
 indra/llui/lltexteditor.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 73f961b36b..1a49b94c23 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1459,6 +1459,10 @@ void LLTextEditor::pasteHelper(bool is_primary)
 // Clean up string (replace tabs and remove characters that our fonts don't support).
 void LLTextEditor::cleanStringForPaste(LLWString & clean_string)
 {
+	std::string clean_string_utf = wstring_to_utf8str(clean_string);
+	std::replace( clean_string_utf.begin(), clean_string_utf.end(), '\r', '\n');
+	clean_string = utf8str_to_wstring(clean_string_utf);
+
 	LLWStringUtil::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB);
 	if( mAllowEmbeddedItems )
 	{
-- 
cgit v1.2.3


From 66a9db4b06fed51477db1c09901b5120b36ce11c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 22 Mar 2017 18:41:51 +0200
Subject: MAINT-7225 MAC build fix

---
 indra/newview/llblocklist.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 54617169c8..1eab2d8e23 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -220,7 +220,7 @@ void LLBlockList::refresh()
 		else if(mActionType == REMOVE)
 		{
 			if ((mute.mID.notNull() && selected.isUUID() && selected.asUUID() == mute.mID)
-				|| mute.mID.isNull() && selected.isString() && selected.asString() == mute.mName)
+				|| (mute.mID.isNull() && selected.isString() && selected.asString() == mute.mName))
 			{
 				// we are going to remove currently selected item, so select next item and save the selection to restore it
 				if (!selectNextItemPair(false, true))
-- 
cgit v1.2.3


From 11e499f44b328a58b0170c8a5ddaa958b76e7c20 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 21 Mar 2017 02:22:29 +0200
Subject: MAINT-6789 Add More now won't affect Edit Appearance perfomance
 during fetch unless visible

---
 indra/newview/llfilteredwearablelist.cpp | 30 +++++++++++++++++++++++++++++-
 indra/newview/llfilteredwearablelist.h   | 12 +++++++++---
 indra/newview/llinventoryitemslist.h     |  5 +++++
 indra/newview/llpaneloutfitedit.cpp      |  6 +++++-
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index f2af9b5300..e67a6a2b77 100644
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -37,6 +37,7 @@
 LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)
 : mWearableList(list)
 , mCollector(collector)
+, mListStale(true)
 {
 	llassert(mWearableList);
 	gInventory.addObserver(this);
@@ -64,7 +65,16 @@ void LLFilteredWearableListManager::changed(U32 mask)
 		return;
 	}
 
-	populateList();
+	if (mWearableList->isInVisibleChain() || mWearableList->getForceRefresh())
+	{
+		// Todo: current populateList() is time consuming and changed() is time-sensitive,
+		// either move from here or optimize
+		populateList();
+	}
+	else
+	{
+		mListStale = true;
+	}
 }
 
 void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor* collector)
@@ -73,13 +83,31 @@ void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor
 	populateList();
 }
 
+void LLFilteredWearableListManager::populateIfNeeded()
+{
+	if (mListStale)
+	{
+		populateList();
+	}
+}
+
+LLTrace::BlockTimerStatHandle FTM_MANAGER_LIST_POPULATION("Manager List Population");
+
 void LLFilteredWearableListManager::populateList()
 {
+	LL_RECORD_BLOCK_TIME(FTM_MANAGER_LIST_POPULATION);
+
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
 
 	if(mCollector)
 	{
+		// Too slow with large inventory!
+		// Consider refactoring into "request once, append ids on changed()", since
+		// Inventory observer provides ids of changed items this should be possible,
+		// but will likely require modifying LLInventoryItemsList to avoid code-repeats.
+		// Or make something like "gather everything and filter manually on idle"
+		mListStale = false;
 		gInventory.collectDescendentsIf(
 				gInventory.getRootFolderID(),
 				cat_array,
diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h
index f44ab1466f..197302f41d 100644
--- a/indra/newview/llfilteredwearablelist.h
+++ b/indra/newview/llfilteredwearablelist.h
@@ -52,9 +52,9 @@ public:
 	void setFilterCollector(LLInventoryCollectFunctor* collector);
 
 	/**
-	 * Populates wearable list with filtered data.
-	 */
-	void populateList();
+	* Populates wearable list with filtered data in case there were any updates.
+	*/
+	void populateIfNeeded();
 
 	/**
 	 * Drop operation
@@ -62,8 +62,14 @@ public:
 	void holdProgress();
 
 private:
+	/**
+	* Populates wearable list with filtered data.
+	*/
+	void populateList();
+
 	LLInventoryItemsList* mWearableList;
 	LLInventoryCollectFunctor* mCollector;
+	bool mListStale;
 };
 
 #endif //LL_LLFILTEREDWEARABLELIST_H
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index fe05c2ed7c..ce41105f98 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -61,6 +61,11 @@ public:
 	 */
 	void setForceRefresh(bool force_refresh){ mForceRefresh = force_refresh; }
 
+	/**
+	* If refreshes when invisible.
+	*/
+	bool getForceRefresh(){ return mForceRefresh;  }
+
 	virtual bool selectItemByValue(const LLSD& value, bool select = true);
 
 	void updateSelection();
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 208ee77f2d..3f6bdde127 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -578,7 +578,6 @@ void LLPanelOutfitEdit::onOpen(const LLSD& key)
 		// *TODO: this method is called even panel is not visible to user because its parent layout panel is hidden.
 		// So, we can defer initializing a bit.
 		mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mListViewItemTypes[LVIT_ALL]->collector);
-		mWearableListManager->populateList();
 		displayCurrentOutfit();
 		mInitialized = true;
 	}
@@ -632,6 +631,10 @@ void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)
 		// Reset mWearableItemsList position to top. See EXT-8180.
 		mWearableItemsList->goToTop();
 	}
+	else
+	{
+		mWearableListManager->populateIfNeeded();
+	}
 
 	//switching button bars
 	getChildView("no_add_wearables_button_bar")->setVisible( !show_add_wearables);
@@ -661,6 +664,7 @@ void LLPanelOutfitEdit::showWearablesListView()
 	{
 		updateWearablesPanelVerbButtons();
 		updateFiltersVisibility();
+		mWearableListManager->populateIfNeeded();
 	}
 	mListViewBtn->setToggleState(TRUE);
 }
-- 
cgit v1.2.3


From eddcb4385165316831d19d514ecfe5e9edac4234 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 21 Mar 2017 16:18:23 +0200
Subject: MAINT-7224 Chat logs move down, leaving huge empty space

---
 indra/llui/lltextbase.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 88a5c3a587..f3a99dcef2 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1522,7 +1522,7 @@ void LLTextBase::reflow()
 		}
 
 		S32 line_height = 0;
-		S32 seg_line_offset = line_count;
+		S32 seg_line_offset = line_count + 1;
 
 		while(seg_iter != mSegments.end())
 		{
-- 
cgit v1.2.3


From ae59476522c1d91074df53968b28da182c25381c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 22 Mar 2017 15:53:17 +0200
Subject: MAINT-7225 Blocks list wasn't updating corretly for name based
 muting.

---
 indra/newview/llblocklist.cpp | 53 +++++++++++++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 1589db15a5..54617169c8 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -130,7 +130,14 @@ BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 void LLBlockList::removeListItem(const LLMute* mute)
 {
-	removeItemByUUID(mute->mID);
+	if (mute->mID.notNull())
+	{
+		removeItemByUUID(mute->mID);
+	}
+	else
+	{
+		removeItemByValue(mute->mName);
+	}
 }
 
 void LLBlockList::hideListItem(LLBlockedListItem* item, bool show)
@@ -178,7 +185,14 @@ void LLBlockList::addNewItem(const LLMute* mute)
 	{
 		item->highlightName(mNameFilter);
 	}
-	addItem(item, item->getUUID(), ADD_BOTTOM);
+	if (item->getUUID().notNull())
+	{
+		addItem(item, item->getUUID(), ADD_BOTTOM);
+	}
+	else
+	{
+		addItem(item, item->getName(), ADD_BOTTOM);
+	}
 }
 
 void LLBlockList::refresh()
@@ -186,7 +200,8 @@ void LLBlockList::refresh()
 	bool have_filter = !mNameFilter.empty();
 
 	// save selection to restore it after list rebuilt
-	LLUUID selected = getSelectedUUID(), next_selected;
+	LLSD selected = getSelectedValue();
+	LLSD next_selected;
 
 	if(mShouldAddAll)	// creating list of blockers
 	{
@@ -204,14 +219,15 @@ void LLBlockList::refresh()
 		}
 		else if(mActionType == REMOVE)
 		{
-			if(selected == mute.mID)
+			if ((mute.mID.notNull() && selected.isUUID() && selected.asUUID() == mute.mID)
+				|| mute.mID.isNull() && selected.isString() && selected.asString() == mute.mName)
 			{
 				// we are going to remove currently selected item, so select next item and save the selection to restore it
-	if (!selectNextItemPair(false, true))
-	{
-		selectNextItemPair(true, true);
-	}
-				next_selected = getSelectedUUID();
+				if (!selectNextItemPair(false, true))
+				{
+					selectNextItemPair(true, true);
+				}
+				next_selected = getSelectedValue();
 			}
 			removeListItem(&mute);
 		}
@@ -237,15 +253,18 @@ void LLBlockList::refresh()
 	}
 	mPrevNameFilter = mNameFilter;
 
-	if (getItemPair(selected))
-	{
-		// restore previously selected item
-		selectItemPair(getItemPair(selected), true);
-	}
-	else if (getItemPair(next_selected))
+	if (selected.isDefined())
 	{
-		// previously selected item was removed, so select next item
-		selectItemPair(getItemPair(next_selected), true);
+		if (getItemPair(selected))
+		{
+			// restore previously selected item
+			selectItemPair(getItemPair(selected), true);
+		}
+		else if (next_selected.isDefined() && getItemPair(next_selected))
+		{
+			// previously selected item was removed, so select next item
+			selectItemPair(getItemPair(next_selected), true);
+		}
 	}
 	mMuteListSize = LLMuteList::getInstance()->getMutes().size();
 
-- 
cgit v1.2.3


From 3e6aafb489dec10f695f5dd2e04395ff473cfc50 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 22 Mar 2017 18:41:51 +0200
Subject: MAINT-6789 MAC build fix

---
 indra/newview/llblocklist.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 54617169c8..1eab2d8e23 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -220,7 +220,7 @@ void LLBlockList::refresh()
 		else if(mActionType == REMOVE)
 		{
 			if ((mute.mID.notNull() && selected.isUUID() && selected.asUUID() == mute.mID)
-				|| mute.mID.isNull() && selected.isString() && selected.asString() == mute.mName)
+				|| (mute.mID.isNull() && selected.isString() && selected.asString() == mute.mName))
 			{
 				// we are going to remove currently selected item, so select next item and save the selection to restore it
 				if (!selectNextItemPair(false, true))
-- 
cgit v1.2.3


From 83694e1404b27a74053a4567b9546e06845f5fbb Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 23 Mar 2017 12:08:31 +0200
Subject: MAINT-7237 Change Flickr upload button label & window title name

---
 indra/newview/skins/default/xui/en/floater_flickr.xml     | 2 +-
 indra/newview/skins/default/xui/en/panel_flickr_photo.xml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml
index 52ef16c7e8..3b9c4894c1 100644
--- a/indra/newview/skins/default/xui/en/floater_flickr.xml
+++ b/indra/newview/skins/default/xui/en/floater_flickr.xml
@@ -9,7 +9,7 @@
   save_rect="true"
   single_instance="true"
   reuse_instance="true"
-  title="UPLOAD TO FLICKR"
+  title="SHARE TO FLICKR"
   height="590"
   width="272">
   <panel
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
index e31695645d..6074ab9ef6 100644
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
@@ -237,7 +237,7 @@ Use "" for multi-word tags
            top_pad="7"
            left="10"
            height="23"
-           label="Upload"
+           label="Share"
            name="post_photo_btn"
            width="100">
             <button.commit_callback
-- 
cgit v1.2.3


From f5819240fa1f76835e0bb6c05e73ec91bd7f9028 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 24 Mar 2017 19:09:54 +0200
Subject: MAINT-380 Add "Duplicate" feature into Build-Object sunbmenu

---
 indra/llui/lleditmenuhandler.h                     |  3 ---
 indra/newview/llviewermenu.cpp                     | 25 ++--------------------
 indra/newview/skins/default/xui/en/menu_edit.xml   |  9 --------
 indra/newview/skins/default/xui/en/menu_viewer.xml |  9 ++++++++
 4 files changed, 11 insertions(+), 35 deletions(-)

diff --git a/indra/llui/lleditmenuhandler.h b/indra/llui/lleditmenuhandler.h
index 0932f094ef..cd4fea8c52 100644
--- a/indra/llui/lleditmenuhandler.h
+++ b/indra/llui/lleditmenuhandler.h
@@ -58,9 +58,6 @@ public:
 	
 	virtual void	deselect() {};
 	virtual BOOL	canDeselect() const { return FALSE; }
-	
-	virtual void	duplicate() {};
-	virtual BOOL	canDuplicate() const { return FALSE; }
 
 	// TODO: Instead of being a public data member, it would be better to hide it altogether
 	// and have a "set" method and then a bunch of static versions of the cut, copy, paste
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 605d1a04e6..c68f6b8a15 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4177,27 +4177,6 @@ class LLViewToggleUI : public view_listener_t
 	}
 };
 
-class LLEditDuplicate : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		if(LLEditMenuHandler::gEditMenuHandler)
-		{
-			LLEditMenuHandler::gEditMenuHandler->duplicate();
-		}
-		return true;
-	}
-};
-
-class LLEditEnableDuplicate : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDuplicate();
-		return new_value;
-	}
-};
-
 void handle_duplicate_in_place(void*)
 {
 	LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL;
@@ -8710,7 +8689,6 @@ void initialize_edit_menu()
 	view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete");
 	view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll");
 	view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect");
-	view_listener_t::addMenu(new LLEditDuplicate(), "Edit.Duplicate");
 	view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff");
 	view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
 	view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
@@ -8720,7 +8698,6 @@ void initialize_edit_menu()
 	view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
 	view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
 	view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
-	view_listener_t::addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate");
 
 }
 
@@ -9131,6 +9108,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
 	view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar");
 	view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
+	commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance()));
 	view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
 	view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
 
@@ -9152,6 +9130,7 @@ void initialize_menus()
 	enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
 
 	view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
+	enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
 	view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
 
 	enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
diff --git a/indra/newview/skins/default/xui/en/menu_edit.xml b/indra/newview/skins/default/xui/en/menu_edit.xml
index 99061e089a..6f83756f83 100644
--- a/indra/newview/skins/default/xui/en/menu_edit.xml
+++ b/indra/newview/skins/default/xui/en/menu_edit.xml
@@ -62,15 +62,6 @@
     <menu_item_call.on_enable
      function="Edit.EnableDelete" />
   </menu_item_call>
-  <menu_item_call
-   label="Duplicate"
-   name="Duplicate"
-   shortcut="control|D">
-    <menu_item_call.on_click
-     function="Edit.Duplicate" />
-    <menu_item_call.on_enable
-     function="Edit.EnableDuplicate" />
-  </menu_item_call>
   <menu_item_separator/>
   <menu_item_call
    label="Select All"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c96b7ae673..12df3749f6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1024,6 +1024,15 @@
                function="Object.Return" />
 			<menu_item_call.on_enable
                function="Object.EnableReturn" />
+          </menu_item_call>
+          <menu_item_call
+           label="Duplicate"
+           name="DuplicateObject"
+           shortcut="control|D">
+            <menu_item_call.on_click
+               function="Object.Duplicate" />
+            <menu_item_call.on_enable
+               function="Object.EnableDuplicate" />
           </menu_item_call>
 		</menu>
         <menu
-- 
cgit v1.2.3


From 5a73e8fc102fbf94ec6660e3be1220d68855ebd3 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 27 Mar 2017 15:20:24 +0300
Subject: MAINT-7238 Change InventoryMarketplaceError text

---
 indra/newview/llfloatermarketplacelistings.cpp | 1 +
 indra/newview/skins/default/xui/en/strings.xml | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 18f0bc4498..889d017389 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -603,6 +603,7 @@ void LLFloaterMarketplaceListings::updateView()
             text = LLTrans::getString("InventoryMarketplaceError", subs);
             title = LLTrans::getString("InventoryOutboxErrorTitle");
             tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+            LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
         }
     
         mInventoryText->setValue(text);
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 5f686a87be..d6c06b0ecc 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2312,7 +2312,8 @@ We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace
 The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
 	</string>
 	<string name="InventoryMarketplaceError">
-This feature is currently in Beta. Please add your name to this [http://goo.gl/forms/FCQ7UXkakz Google form] if you would like to participate.
+An error occurred while opening Marketplace Listings.
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
 	</string>
 	<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>
 	<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>
-- 
cgit v1.2.3


From f1e00870dfef809b2c2842051140cc720650649a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 28 Mar 2017 11:42:17 +0300
Subject: MAINT-6980 FIXED Ctrl + Alt + Shift + B does not force a crash on mac

---
 indra/newview/llappviewer.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 62e32c0bdc..f53ba01d37 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5592,6 +5592,8 @@ void LLAppViewer::forceErrorBreakpoint()
    	LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
 #ifdef LL_WINDOWS
     DebugBreak();
+#else
+    asm ("int $3");
 #endif
     return;
 }
-- 
cgit v1.2.3


From 7603eb51c58db135cf5c49eb10247c8e9ea46bd8 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 28 Mar 2017 12:30:20 +0300
Subject: Backed out changeset: 50e72280019f

---
 indra/newview/llagentcamera.cpp | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 7723dbf978..e335eabd1a 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1537,11 +1537,6 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 	}
 	else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
-		LLVector3 focus_target = isAgentAvatarValid()
-			? gAgentAvatarp->mHeadp->getWorldPosition()
-			: gAgent.getPositionAgent();
-		LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
-		mFocusTargetGlobal = focus_target_global;
 		return mFocusTargetGlobal;
 	}
 	else if (!mFocusOnAvatar)
-- 
cgit v1.2.3


From 45dd355d46dc8ea5a0a6934722ffc76f9d955a9f Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 28 Mar 2017 13:56:01 +0300
Subject: MAINT-1858 Fixed camera not looking at avatar if "Editing Appearance"
 while moving

---
 indra/newview/llagentcamera.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index e335eabd1a..5b9f1b9d4f 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1537,6 +1537,14 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 	}
 	else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
+		if (mFocusOnAvatar)
+		{
+			LLVector3 focus_target = isAgentAvatarValid()
+				? gAgentAvatarp->mHeadp->getWorldPosition()
+				: gAgent.getPositionAgent();
+			LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
+			mFocusTargetGlobal = focus_target_global;
+		}
 		return mFocusTargetGlobal;
 	}
 	else if (!mFocusOnAvatar)
-- 
cgit v1.2.3


From 084f7cf44a3259242d28264f0bb191004282dd9c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 28 Mar 2017 16:24:50 +0300
Subject: MAINT-7257 Added null check for volume manager

---
 indra/llprimitive/llprimitive.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 186716609c..bfa65666b5 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -172,7 +172,7 @@ LLPrimitive::~LLPrimitive()
 {
 	clearTextureList();
 	// Cleanup handled by volume manager
-	if (mVolumep)
+	if (mVolumep && sVolumeManager)
 	{
 		sVolumeManager->unrefVolume(mVolumep);
 	}
-- 
cgit v1.2.3


From f53e142e7dc0d613f6d3d9b3d276cdc8843cb143 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 30 Mar 2017 00:22:36 +0300
Subject: MAINT-7128 Crash in LLDrawable::cleanupReferences - more informative
 logging

---
 indra/newview/lldrawpoolavatar.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 499cf76bff..b221221f16 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -2063,7 +2063,9 @@ void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
 			}
 			else
 			{
-				LL_ERRS() << "Face reference data corrupt for rigged type " << i << LL_ENDL;
+				LL_ERRS() << "Face reference data corrupt for rigged type " << i
+					<< ((mRiggedFace[i].size() <= index) ? "; wrong index (out of bounds)" : (mRiggedFace[i][index] != facep) ? "; wrong face pointer" : "")
+					<< LL_ENDL;
 			}
 		}
 	}
-- 
cgit v1.2.3


From 5e926ece20407e5f0742a355d890e2f208ddca19 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 30 Mar 2017 16:30:01 +0300
Subject: MAINT-7245 Use Experience Box in LSL Editor will not show as checked
 if containing object is in another region

---
 indra/llmessage/llexperiencecache.cpp | 26 +++++++++++++++++++++-----
 indra/llmessage/llexperiencecache.h   |  3 ++-
 indra/newview/llpreviewscript.cpp     | 10 ++++++++--
 indra/newview/llsidepaneliteminfo.cpp | 11 ++++++++---
 4 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 779d1d9d99..aa7b3c1260 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -540,18 +540,34 @@ void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const
     }
 
     LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated",
-        boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, fn));
+        boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId,  std::string(), fn));
 }
 
-void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, ExperienceGetFn_t fn)
+void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
+{
+    if (mCapability.empty())
+    {
+        LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
+        return;
+    }
+
+    LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated",
+        boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, url, fn));
+}
+
+void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, std::string url, ExperienceGetFn_t fn)
 {
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest());
-    std::string url = mCapability("GetMetadata");
 
     if (url.empty())
     {
-        LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
-        return;
+        url = mCapability("GetMetadata");
+
+        if (url.empty())
+        {
+            LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
+            return;
+        }
     }
 
     LLSD fields;
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index 8ee7080d38..f9ff69c2b6 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -64,6 +64,7 @@ public:
 
     //-------------------------------------------
     void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn);
+    void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
     void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
     void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
 
@@ -148,7 +149,7 @@ private:
     void requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, RequestQueue_t);
     void requestExperiences();
 
-    void fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID, LLUUID, ExperienceGetFn_t);
+    void fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID, LLUUID, std::string, ExperienceGetFn_t);
     void findExperienceByNameCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, int, ExperienceGetFn_t);
     void getGroupExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID , ExperienceGetFn_t);
     void regionExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, CapabilityQuery_t regioncaps, bool update, LLSD experiences, ExperienceGetFn_t fn);
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index f28ffce602..5cdc5dfd38 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -1870,8 +1870,14 @@ void LLLiveLSLEditor::loadAsset()
 
 			if(item)
 			{
-                LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(),
-                        boost::bind(&LLLiveLSLEditor::setAssociatedExperience, getDerivedHandle<LLLiveLSLEditor>(), _1));
+				LLViewerRegion* region = object->getRegion();
+				std::string url = std::string();
+				if(region)
+				{
+					url = region->getCapability("GetMetadata");
+				}
+				LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), url,
+					boost::bind(&LLLiveLSLEditor::setAssociatedExperience, getDerivedHandle<LLLiveLSLEditor>(), _1));
 
 				bool isGodlike = gAgent.isGodlike();
 				bool copyManipulate = gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index af2173dd17..3c58dd7194 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -46,6 +46,7 @@
 #include "llviewerobjectlist.h"
 #include "llexperiencecache.h"
 #include "lltrans.h"
+#include "llviewerregion.h"
 
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -327,9 +328,13 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
         LLTextBox* tb = getChild<LLTextBox>("LabelItemExperience");
         tb->setText(getString("loading_experience"));
         tb->setVisible(TRUE);
-
-        LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), 
-            boost::bind(&LLSidepanelItemInfo::setAssociatedExperience, getDerivedHandle<LLSidepanelItemInfo>(), _1));
+        std::string url = std::string();
+        if(object && object->getRegion())
+        {
+            url = object->getRegion()->getCapability("GetMetadata");
+        }
+        LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), url,
+                boost::bind(&LLSidepanelItemInfo::setAssociatedExperience, getDerivedHandle<LLSidepanelItemInfo>(), _1));
     }
     
 	//////////////////////
-- 
cgit v1.2.3


From 7e13f981d2858a5946954c57066aab7fa50cabd1 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 30 Mar 2017 21:35:01 +0300
Subject: Add multiline support for MAINT-6959

---
 .../default/xui/en/panel_preferences_uploads.xml     | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
index 487da54fdf..343c2db2f1 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
@@ -38,13 +38,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_textures"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
   
   <text
    type="string"
@@ -62,13 +63,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_sounds"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
   
   <text
    type="string"
@@ -86,13 +88,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_animation"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
 
   <text
    type="string"
@@ -110,13 +113,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_models"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
 
   <text
    type="string"
-- 
cgit v1.2.3


From 37c5150a3c7809dee7a514acc8fdf5bd7db6ba0f Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 19 Apr 2017 15:11:10 -0400
Subject: Added tag 5.0.4-release for changeset 022709ef76a3

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index 47413e0553..a832521ac3 100755
--- a/.hgtags
+++ b/.hgtags
@@ -525,3 +525,4 @@ b41e1e7c7876f7656c505f552b5888b4e478f92b 5.0.0-release
 c9ce2295012995e3cf5c57bcffcb4870b94c649f 5.0.1-release
 cea1632c002c065985ebea15eeeb4aac90f50545 5.0.2-release
 02c24e9f4f7d8aa0de75f27817dda098582f4936 5.0.3-release
+022709ef76a331cac1ba6ef1a6da8a5e9ef63f5a 5.0.4-release
-- 
cgit v1.2.3


From f62b5503285d828813d87779fa0658ee5f122ac5 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 19 Apr 2017 15:11:10 -0400
Subject: increment viewer version to 5.0.5

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 2d6c0bcf19..ab0fa336dd 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-5.0.4
+5.0.5
-- 
cgit v1.2.3