diff --git a/.github/labeler.yaml b/.github/labeler.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d31a361baf2212b092bc7dca01ccf0f0e0b20ce4
--- /dev/null
+++ b/.github/labeler.yaml
@@ -0,0 +1,78 @@
+llappearance:
+  - indra/llappearance/**/*
+  
+llaudio:
+  - indra/llaudio/**/*
+
+llcharacter:
+  - indra/llcharacter/**/*
+
+llcommon:
+  - indra/llcommon/**/*
+
+llcorehttp:
+  - indra/llcorehttp/**/*
+
+llcrashlogger:
+  - indra/llcrashlogger/**/*
+
+llfilesystem:
+  - indra/llfilesystem/**/*
+
+llimage:
+  - indra/llimage/**/*
+
+llimagej2coj:
+  - indra/llimagej2coj/**/*
+
+llinventory:
+  - indra/llinventory/**/*
+
+llkdu:
+  - indra/llkdu/**/*
+
+llmath:
+  - indra/llmath/**/*
+
+llmeshoptimizer:
+  - indra/llmeshoptimizer/**/*
+
+llmessage:
+  - indra/llmessage/**/*
+
+llplugin:
+  - indra/llplugin/**/*
+
+llprimitive:
+  - indra/llprimitive/**/*
+
+llrender:
+  - indra/llrender/**/*
+
+llui:
+  - indra/llui/**/*
+
+llwindow:
+  - indra/llwindow/**/*
+
+llxml:
+  - indra/llxml/**/*
+
+cmake:
+  - '**/*.cmake'
+  - '**/*/cmake/*'
+  - '**/CMakeLists.txt'
+
+python:
+  - '**/*.py'
+
+c/cpp:
+  - '**/*.c'
+  - '**/*.cpp'
+  - '**/*.cxx'
+  - '**/*.h'
+  - '**/*.hpp'
+  - '**/*.hxx'
+  - '**/*.i'
+  - '**/*.inl'
+  - '**/*.y'
diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fa180c66c9763bfcc7bec83d4c901e7526790574
--- /dev/null
+++ b/.github/workflows/cla.yaml
@@ -0,0 +1,25 @@
+name: Check CLA
+
+on:
+  issue_comment:
+    types: [created]
+  pull_request_target:
+    types: [opened, closed, synchronize]
+
+jobs:
+  cla:
+    name: Check CLA
+    runs-on: ubuntu-latest
+    steps:
+      - name: CLA Assistant
+        if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
+        uses: secondlife-3p/contributor-assistant@v2
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          PERSONAL_ACCESS_TOKEN: ${{ secrets.SHARED_CLA_TOKEN }}
+        with:
+          branch: main
+          path-to-document: https://github.com/secondlife/cla/blob/master/CLA.md
+          path-to-signatures: signatures.json
+          remote-organization-name: secondlife
+          remote-repository-name: cla-signatures
diff --git a/.github/workflows/label.yaml b/.github/workflows/label.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6e41d8aa2d808e5edd3e99bc67067ba5353b7b69
--- /dev/null
+++ b/.github/workflows/label.yaml
@@ -0,0 +1,15 @@
+name: Pull Request Labeler
+on:
+  - pull_request_target
+
+jobs:
+  triage:
+    permissions:
+      contents: read
+      pull-requests: write
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/labeler@v4
+        with:
+          configuration-path: .github/labeler.yaml
+          repo-token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/doc/LGPL-licence.txt b/LICENSE
similarity index 100%
rename from doc/LGPL-licence.txt
rename to LICENSE
diff --git a/autobuild.xml b/autobuild.xml
index f88e92aafb2ea3cf91cc4ce6d0c330b9c77322e8..641aa2b4f06381e358fd716fd735c856dd10d2e9 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2236,9 +2236,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1dda5fb3bb649b0ab5a93f22df7cb11e</string>
+              <string>2e8d817e7837dd6f4284b13fa3f5c15e</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2248,9 +2248,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>30d1386d0a6883d898fc56757a789b8b</string>
+              <string>3efa80faaf537e39a77218cd6efa9409</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -2261,7 +2261,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>3.0.569958</string>
+        <string>3.0.575083</string>
       </map>
       <key>vlc-bin</key>
       <map>
diff --git a/doc/LGPL-license.txt b/doc/LGPL-license.txt
new file mode 100755
index 0000000000000000000000000000000000000000..4362b49151d7b34ef83b3067a8f9c9f877d72a0e
--- /dev/null
+++ b/doc/LGPL-license.txt
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 9368781c9a6cc27e81d9a2a3b4830da743a261eb..4cabb84b1034af760667cf16d4f0d9384e2edc93 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -282,6 +282,7 @@ Beq Janus
 	SL-11300
 	SL-15709
 	SL-16021
+	SL-18637
 Beth Walcher
 Bezilon Kasei
 Biancaluce Robbiani
diff --git a/doc/sl-logo-dark.png b/doc/sl-logo-dark.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa9ef32aea03eef5d740df05964bb60ddd8b05fd
Binary files /dev/null and b/doc/sl-logo-dark.png differ
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 1c0f61ab470324e48c06e2fa6ca43e35b36ff533..77469578cbab7c9d87e436db32b0f7a367c6267a 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -109,7 +109,6 @@ set(llcommon_SOURCE_FILES
     llsys.cpp
     lltempredirect.cpp
     llthread.cpp
-    llthreadlocalstorage.cpp
     llthreadsafequeue.cpp
     lltimer.cpp
     lltrace.cpp
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index eddc67474cc13c4d83ee508c1f8de665804735e5..bf475da8c0d7adbe37fd9251e8a81e77d67fefc6 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -30,7 +30,6 @@
 #include "llapr.h"
 #include "llmutex.h"
 #include "apr_dso.h"
-#include "llthreadlocalstorage.h"
 
 apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
 LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@@ -54,7 +53,6 @@ void ll_init_apr()
 		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool("Global APR File Pool", FALSE) ;
 	}
 
-	LLThreadLocalPointerBase::initAllThreadLocalStorage();
 	gAPRInitialized = true;
 }
 
@@ -70,8 +68,6 @@ void ll_cleanup_apr()
 
 	LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
 
-	LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
-
 	if (gAPRPoolp)
 	{
 		apr_pool_destroy(gAPRPoolp);
diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp
deleted file mode 100644
index d8a063e8d53551c06cfc0f55b101bdd30d3c37a1..0000000000000000000000000000000000000000
--- a/indra/llcommon/llthreadlocalstorage.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/** 
- * @file llthreadlocalstorage.cpp
- * @author Richard
- * @date 2013-1-11
- * @brief implementation of thread local storage utility classes
- *
- * $LicenseInfo:firstyear=2013&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 "linden_common.h"
-#include "llthreadlocalstorage.h"
-#include "llapr.h"
-
-//
-//LLThreadLocalPointerBase
-//
-bool LLThreadLocalPointerBase::sInitialized = false;
-
-void LLThreadLocalPointerBase::set( void* value )
-{
-	llassert(sInitialized && mThreadKey);
-
-	apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
-	if (result != APR_SUCCESS)
-	{
-		ll_apr_warn_status(result);
-		LL_ERRS() << "Failed to set thread local data" << LL_ENDL;
-	}
-}
-
-void* LLThreadLocalPointerBase::get() const
-{
-	// llassert(sInitialized);
-	void* ptr;
-	apr_status_t result =
-		apr_threadkey_private_get(&ptr, mThreadKey);
-	if (result != APR_SUCCESS)
-	{
-		ll_apr_warn_status(result);
-		LL_ERRS() << "Failed to get thread local data" << LL_ENDL;
-	}
-	return ptr;
-}
-
-
-void LLThreadLocalPointerBase::initStorage( )
-{
-	apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
-	if (result != APR_SUCCESS)
-	{
-		ll_apr_warn_status(result);
-		LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL;
-	}
-}
-
-void LLThreadLocalPointerBase::destroyStorage()
-{
-	if (sInitialized)
-	{
-		if (mThreadKey)
-		{
-			apr_status_t result = apr_threadkey_private_delete(mThreadKey);
-			if (result != APR_SUCCESS)
-			{
-				ll_apr_warn_status(result);
-				LL_ERRS() << "Failed to delete thread local data" << LL_ENDL;
-			}
-		}
-	}
-}
-
-//static
-void LLThreadLocalPointerBase::initAllThreadLocalStorage()
-{
-	if (!sInitialized)
-	{
-		for (auto& base : instance_snapshot())
-		{
-			base.initStorage();
-		}
-		sInitialized = true;
-	}
-}
-
-//static
-void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
-{
-	if (sInitialized)
-	{
-		//for (auto& base : instance_snapshot())
-		//{
-		//	base.destroyStorage();
-		//}
-		sInitialized = false;
-	}
-}
diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h
index 1c0cdeded3e9e28fc0e2f2f00810c6f1fd5b03d1..bdd28ec8653ee92feda114f991e04b118833b561 100644
--- a/indra/llcommon/llthreadlocalstorage.h
+++ b/indra/llcommon/llthreadlocalstorage.h
@@ -30,99 +30,6 @@
 
 #include "llinstancetracker.h"
 
-class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
-{
-public:
-	LLThreadLocalPointerBase()
-	:	mThreadKey(NULL)
-	{
-		if (sInitialized)
-		{
-			initStorage();
-		}
-	}
-
-	LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
-	:	mThreadKey(NULL)
-	{
-		if (sInitialized)
-		{
-			initStorage();
-		}
-	}
-
-	~LLThreadLocalPointerBase()
-	{
-		destroyStorage();
-	}
-
-	static void initAllThreadLocalStorage();
-	static void destroyAllThreadLocalStorage();
-
-protected:
-	void set(void* value);
-
-	void* get() const;
-
-	void initStorage();
-	void destroyStorage();
-
-protected:
-	struct apr_threadkey_t*	mThreadKey;
-	static bool				sInitialized;
-};
-
-template <typename T>
-class LLThreadLocalPointer : public LLThreadLocalPointerBase
-{
-public:
-
-	LLThreadLocalPointer() = default;
-
-	explicit LLThreadLocalPointer(T* value)
-	{
-		set(value);
-	}
-
-
-	LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
-	:	LLThreadLocalPointerBase(other)
-	{
-		set(other.get());		
-	}
-
-	LL_FORCE_INLINE T* get() const
-	{
-		return (T*)LLThreadLocalPointerBase::get();
-	}
-
-	T* operator -> () const
-	{
-		return (T*)get();
-	}
-
-	T& operator*() const
-	{
-		return *(T*)get();
-	}
-
-	LLThreadLocalPointer<T>& operator = (T* value)
-	{
-		set((void*)value);
-		return *this;
-	}
-
-	bool operator ==(const T* other) const
-	{
-		if (!sInitialized) return false;
-		return get() == other;
-	}
-
-	bool isNull() const { return !sInitialized || get() == NULL; }
-
-	bool notNull() const { return sInitialized && get() != NULL; }
-};
-
 template<typename DERIVED_TYPE>
 class LLThreadLocalSingletonPointer
 {
@@ -138,10 +45,10 @@ class LLThreadLocalSingletonPointer
 	}
 
 private:
-	static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
+	static thread_local DERIVED_TYPE* sInstance;
 };
 
 template<typename DERIVED_TYPE>
-LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
+thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
 
 #endif // LL_LLTHREADLOCALSTORAGE_H
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index f59b207ded2d26634f8a8b266cb4ed7fc0e14637..acdda5fe1e2af3ad7af9da39e54dc8d1febbaf50 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description )
 	mDescription(description ? description : "")
 {
 #ifndef LL_RELEASE_FOR_DOWNLOAD
-	if (LLTrace::get_thread_recorder().notNull())
+	if (LLTrace::get_thread_recorder() != NULL)
 	{
 		LL_ERRS() << "Attempting to declare trace object after program initialization.  Trace objects should be statically initialized." << LL_ENDL;
 	}
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 34299f5a29a3f55188c5f7b465d0b1c4fdcb79db..fe447d531923d7c4a8cb15614993b5941743ab8b 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent()
 	mStackTimers.makeCurrent();
 	mMemStats.makeCurrent();
 
-	ThreadRecorder* thread_recorder = get_thread_recorder().get();
+	ThreadRecorder* thread_recorder = get_thread_recorder();
 	AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
 	// update stacktimer parent pointers
 	for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++)
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 00edb584e06b2d28cbe264345f535706fd4856e3..0cf3a0e0b92ab3b45249ba9701e8f353122f0c06 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -91,7 +91,7 @@ Recording::~Recording()
 	// allow recording destruction without thread recorder running, 
 	// otherwise thread shutdown could crash if a recording outlives the thread recorder
 	// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
-	if (isStarted() && LLTrace::get_thread_recorder().notNull())
+	if (isStarted() && LLTrace::get_thread_recorder() != NULL)
 	{
 		LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
 	}
@@ -108,9 +108,9 @@ void Recording::update()
 
 		// must have 
 		llassert(mActiveBuffers != NULL 
-				&& LLTrace::get_thread_recorder().notNull());
+				&& LLTrace::get_thread_recorder() != NULL);
 
-		if(!mActiveBuffers->isCurrent())
+		if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
 		{
 			AccumulatorBufferGroup* buffers = mBuffers.write();
 			LLTrace::get_thread_recorder()->deactivate(buffers);
@@ -140,7 +140,7 @@ void Recording::handleStart()
 	mSamplingTimer.reset();
 	mBuffers.setStayUnique(true);
 	// must have thread recorder running on this thread
-	llassert(LLTrace::get_thread_recorder().notNull());
+	llassert(LLTrace::get_thread_recorder() != NULL);
 	mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
 #endif
 }
@@ -151,7 +151,7 @@ void Recording::handleStop()
 #if LL_TRACE_ENABLED
 	mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
 	// must have thread recorder running on this thread
-	llassert(LLTrace::get_thread_recorder().notNull());
+	llassert(LLTrace::get_thread_recorder() != NULL);
 	LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
 	mActiveBuffers = NULL;
 	mBuffers.setStayUnique(false);
@@ -1176,8 +1176,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
 
 PeriodicRecording& get_frame_recording()
 {
-	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
-	return *sRecording;
+	static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
+	return sRecording;
 }
 
 }
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 0d7b5abdda4b1bc0f1e6bbddcdb1a409b420fb53..b6d28edcc287c7128b1ee0b4b33caefbd28d56c6 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
 	return sMasterThreadRecorder;
 }
 
-LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
+ThreadRecorder*& get_thread_recorder_ptr()
 {
-	static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
+	static thread_local ThreadRecorder* s_thread_recorder;
 	return s_thread_recorder;
 }
 
-const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
+ThreadRecorder* get_thread_recorder()
 {
 	return get_thread_recorder_ptr();
 }
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index a797c6687eaa60e9cda6d1c57b990043346bf706..8fd1e5ef58cc4df9bf1a41c7aa9f316d221995a3 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -32,7 +32,6 @@
 
 #include "llmutex.h"
 #include "lltraceaccumulators.h"
-#include "llthreadlocalstorage.h"
 
 namespace LLTrace
 {
@@ -92,7 +91,7 @@ namespace LLTrace
 
 	};
 
-	const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
+	ThreadRecorder* get_thread_recorder();
 	void set_thread_recorder(ThreadRecorder*);
 
 	void set_master_thread_recorder(ThreadRecorder*);
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index f1892024abbfcb9dc800b2339fb74a96c5c30683..44dca35926981de8c47527092d44eff1fea254ae 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -4989,6 +4989,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
 	{
 		U16 index = mIndices[i];
 
+        if (index >= mNumVertices)
+        {
+            // invalid index
+            // replace with a valid index to avoid crashes
+            index = mNumVertices - 1;
+            mIndices[i] = index;
+
+            // Needs better logging
+            LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL;
+        }
+
 		LLVolumeFace::VertexData cv;
 		getVertexData(index, cv);
 		
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 44e091bde28177809043bfd37041c97bcd3605f3..e82b8e61c9189b11688e8474dfa5a29a51fd5ca9 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -688,7 +688,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance()
 char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock");
 char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID");
 char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel");
-char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage");
 char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats");
 char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos");
 char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit");
@@ -1095,7 +1094,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS
 char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter");
 char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity");
 char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket");
-char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket");
 char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal");
 char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel");
 char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing");
@@ -1289,7 +1287,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get
 char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease");
 char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType");
 char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply");
-char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData");
 char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage");
 char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation");
 char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index f65ee501f92789e16dd91970feb63e8f407f977f..209633c3c91107ec1934736f30e9b29b4dd5a8b6 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -688,7 +688,6 @@ extern char const* const _PREHASH_GroupRolesCount;
 extern char const* const _PREHASH_SimulatorBlock;
 extern char const* const _PREHASH_GroupID;
 extern char const* const _PREHASH_AgentVel;
-extern char const* const _PREHASH_RequestImage;
 extern char const* const _PREHASH_NetStats;
 extern char const* const _PREHASH_AgentPos;
 extern char const* const _PREHASH_AgentSit;
@@ -1095,7 +1094,6 @@ extern char const* const _PREHASH_SortOrder;
 extern char const* const _PREHASH_Hunter;
 extern char const* const _PREHASH_SunAngVelocity;
 extern char const* const _PREHASH_BinaryBucket;
-extern char const* const _PREHASH_ImagePacket;
 extern char const* const _PREHASH_StartGroupProposal;
 extern char const* const _PREHASH_EnergyLevel;
 extern char const* const _PREHASH_PriceForListing;
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 0c63c62946a91ee9055083b06df30a537ad704ac..133313b87603b57bcf5423048d8b51697e3512a3 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -330,7 +330,10 @@ LLModel::EModelStatus load_face_from_dom_triangles(
 			// VFExtents change
 			face.mExtents[0].set(v[0], v[1], v[2]);
 			face.mExtents[1].set(v[0], v[1], v[2]);
-			point_map.clear();
+
+            verts.clear();
+            indices.clear();
+            point_map.clear();
 		}
 	}
 
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 43c511822386d56b8eb3dacfd79e34d2af93ae3c..aa17d453970ee188950ea6e4efae15ed830e37f9 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -59,6 +59,8 @@ class LLMeshSkinInfo : public LLRefCount
     mutable std::vector<S32> mJointNums;
     typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
 	matrix_list_t mInvBindMatrix;
+
+    // bones/joints position overrides
 	matrix_list_t mAlternateBindMatrix;
 
 	LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h
index 136f7454967a3083156b07b2c47e819061165690..027581078a46df3bf0053b4bbb713a4689166c49 100644
--- a/indra/llui/llchat.h
+++ b/indra/llui/llchat.h
@@ -38,7 +38,8 @@ typedef enum e_chat_source_type
 	CHAT_SOURCE_AGENT = 1,
 	CHAT_SOURCE_OBJECT = 2,
 	CHAT_SOURCE_TELEPORT = 3,
-	CHAT_SOURCE_UNKNOWN = 4
+	CHAT_SOURCE_UNKNOWN = 4,
+	CHAT_SOURCE_REGION = 5,
 } EChatSourceType;
 
 typedef enum e_chat_type
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index bba2d2900c0612606817a2ac955640dcd20073be..d47dc63ef9126ab64f9e60345f1836e18588aa2e 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
     // it will work fine in case of decrease of space, but if we get more space or text
     // becomes longer, label will fail to grow so reinit label's dimentions.
     
-    static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
     LLRect label_rect = mLabel->getRect();
-    S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
-    label_rect.mRight = label_rect.mLeft + new_width;
-    mLabel->setRect(label_rect);
+    S32 new_width = rect.getWidth() - label_rect.mLeft;
+    mLabel->reshape(new_width, label_rect.getHeight(), TRUE);
 
 	S32 label_top = label_rect.mTop;
 	mLabel->reshapeToFitText(TRUE);
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 3618a866b9efa2b63902405cd08ead075fead051..f7952fa06dffa49e760ba0bcb4ef4238d83c38ac 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -173,7 +173,7 @@ class LLFolderViewModelItem : public LLRefCount
 	virtual BOOL removeItem() = 0;
 	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
 
-	virtual BOOL isItemCopyable() const = 0;
+	virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0;
 	// [SL:KB] - Patch: Inventory-Actions | Checked: 2013-09-19 (Catznip-3.6)
 	virtual bool isItemLinkable() const = 0;
 	// [/SL:KB]
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 1fe64993af27fc01b12a30f3732a23017719e730..aa79c1f56bb6250463fd41ca2dae820d69e53351 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3418,6 +3418,45 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien
 	return mIsFriendSignal->connect(cb);
 }
 
+bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str)
+{
+    if (filter_str == "" || filter_str == " ")
+    {
+        clearHighlightedItems();
+        return false;
+    }
+    
+    bool res = false;
+
+    setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red));
+
+    std::string filter_str_lc(filter_str);
+    LLStringUtil::toLower(filter_str_lc);
+
+    std::vector<LLScrollListItem*> data = getAllData();
+    std::vector<LLScrollListItem*>::iterator iter = data.begin();
+    while (iter != data.end())
+    {
+        LLScrollListCell* cell = (*iter)->getColumn(0);
+        if (cell)
+        {
+            std::string value = cell->getValue().asString();
+            LLStringUtil::toLower(value);
+            if (value.find(filter_str_lc) == std::string::npos)
+            {
+                (*iter)->setHighlighted(false);
+            }
+            else
+            {
+                (*iter)->setHighlighted(true);
+                res = true;
+            }
+        }
+        iter++;
+    }
+    return res;
+}
+
 void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data)
 {
 	mCallback = callback;
@@ -3429,3 +3468,4 @@ BOOL LLScrollListIcon::handleClick()
 	if(mCallback) return mCallback(mUserData);
 	return FALSE;
 }
+
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 90e91de1c8bbbf488e7c631d5ea7ed968ddc6552..8d636f8665028c9882cddd732f456c031ae82268 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -422,6 +422,8 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	void			dirtyColumns(); // some operation has potentially affected column layout or ordering
 	S32				getLinesPerPage();
 
+    bool highlightMatchingItems(const std::string& filter_str);
+
 	boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
 	{
 		if (!mSortCallback) mSortCallback = new sort_signal_t();
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 4716dc79b8b800da4b9f207f3043e7d4874735bc..b6e8605fa4b93ced702c8eb48efc047ed0d262e0 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
 	// Spin buttons
 	LLButton::Params up_button_params(p.up_button);
 	up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height);
-	up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
+    // Click callback starts within the button and ends within the button,
+    // but LLSpinCtrl handles the action continuosly so subsribers needs to
+    // be informed about click ending even if outside view, use 'up' instead
+	up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
 	up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2));
     up_button_params.commit_on_capture_lost = true;
 
@@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
 
 	LLButton::Params down_button_params(p.down_button);
 	down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height);
-	down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
+	down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
 	down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2));
     down_button_params.commit_on_capture_lost = true;
 	mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index b3e40fb2e496c0d59197835686ac754a53921bf7..57b4baa5c8d4a6c34984f65edbd1af735d411a4b 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -378,30 +378,13 @@ void LLTextBase::onValueChange(S32 start, S32 end)
 {
 }
 
-
-// Draws the black box behind the selected text
-//void LLTextBase::drawSelectionBackground()
-// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
-void LLTextBase::drawSelectionBackground()
+std::vector<LLRect> LLTextBase::getSelctionRects()
 {
-	if( hasSelection() && !mLineInfoList.empty())
-	{
-		highlight_list_t highlights;
-		highlights.push_back(range_pair_t(llmin(mSelectionStart, mSelectionEnd), llmax(mSelectionStart, mSelectionEnd)));
-		drawHighlightsBackground(highlights, mSelectedBGColor);
-	}
-}
+    // Nor supposed to be called without selection
+    llassert(hasSelection());
+    llassert(!mLineInfoList.empty());
 
-void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, const LLColor4& color)
-// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
-{
-//	// Draw selection even if we don't have keyboard focus for search/replace
-//	if( hasSelection() && !mLineInfoList.empty())
-// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
-	if (!mLineInfoList.empty())
-// [/SL:KB]
-	{
-		std::vector<LLRect> selection_rects;
+    std::vector<LLRect> selection_rects;
 
 //		S32 selection_left		= llmin( mSelectionStart, mSelectionEnd );
 //		S32 selection_right		= llmax( mSelectionStart, mSelectionEnd );
@@ -502,6 +485,36 @@ void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, co
 				++itHighlight;
 			}
 // [/SL:KB]
+
+
+    return selection_rects;
+}
+
+// Draws the black box behind the selected text
+//void LLTextBase::drawSelectionBackground()
+// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
+void LLTextBase::drawSelectionBackground()
+{
+	if( hasSelection() && !mLineInfoList.empty())
+	{
+		highlight_list_t highlights;
+		highlights.push_back(range_pair_t(llmin(mSelectionStart, mSelectionEnd), llmax(mSelectionStart, mSelectionEnd)));
+		drawHighlightsBackground(highlights, mSelectedBGColor);
+	}
+}
+
+void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, const LLColor4& color)
+// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
+{
+//	// Draw selection even if we don't have keyboard focus for search/replace
+//	if( hasSelection() && !mLineInfoList.empty())
+// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
+	if (!mLineInfoList.empty())
+// [/SL:KB]
+	{
+		std::vector<LLRect> selection_rects = getSelctionRects();
+
+
 		}
 		
 		// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
@@ -509,7 +522,9 @@ void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, co
 //		const LLColor4& color = mSelectedBGColor;
 		F32 alpha = hasFocus() ? 0.7f : 0.3f;
 		alpha *= getDrawContext().mAlpha;
+
 		LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
+        LLRect content_display_rect = getVisibleDocumentRect();
 
 		for (LLRect selection_rect : selection_rects)
 		{
@@ -2688,7 +2703,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
 	}
 	
 	S32 pos = getLength();
-	S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
+	F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;
 
 	segment_set_t::iterator line_seg_iter;
 	S32 line_seg_offset;
@@ -2700,8 +2715,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
 
 		S32 segment_line_start = segmentp->getStart() + line_seg_offset;
 		S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start;
-		S32 text_width, text_height;
-		bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
+        F32 text_width;
+        S32 text_height;
+		bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height);
 
 		if(newline)
 		{
@@ -2721,8 +2737,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
 			S32 offset;
 			if (!segmentp->canEdit())
 			{
-				S32 segment_width, segment_height;
-				segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
+                F32 segment_width;
+                S32 segment_height;
+				segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height);
 				if (round && local_x - start_x > segment_width / 2)
 				{
 					offset = segment_line_length;
@@ -2769,17 +2786,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
 		return LLRect();
 	}
 
-	LLRect doc_rect;
-
 	// clamp pos to valid values
 	pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1);
 
 	line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare());
 
-	doc_rect.mLeft = line_iter->mRect.mLeft; 
-	doc_rect.mBottom = line_iter->mRect.mBottom;
-	doc_rect.mTop = line_iter->mRect.mTop;
-
 	segment_set_t::iterator line_seg_iter;
 	S32 line_seg_offset;
 	segment_set_t::iterator cursor_seg_iter;
@@ -2787,6 +2798,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
 	getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset);
 	getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset);
 
+    F32 doc_left_precise = line_iter->mRect.mLeft;
+
 	while(line_seg_iter != mSegments.end())
 	{
 		const LLTextSegmentPtr segmentp = *line_seg_iter;
@@ -2794,18 +2807,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
 		if (line_seg_iter == cursor_seg_iter)
 		{
 			// cursor advanced to right based on difference in offset of cursor to start of line
-			S32 segment_width, segment_height;
-			segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
-			doc_rect.mLeft += segment_width;
+            F32 segment_width;
+            S32 segment_height;
+			segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height);
+            doc_left_precise += segment_width;
 
 			break;
 		}
 		else
 		{
 			// add remainder of current text segment to cursor position
-			S32 segment_width, segment_height;
-			segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
-			doc_rect.mLeft += segment_width;
+            F32 segment_width;
+            S32 segment_height;
+			segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height);
+            doc_left_precise += segment_width;
 			// offset will be 0 for all segments after the first
 			line_seg_offset = 0;
 			// go to next text segment on this line
@@ -2813,6 +2828,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const
 		}
 	}
 
+    LLRect doc_rect;
+    doc_rect.mLeft = doc_left_precise;
+    doc_rect.mBottom = line_iter->mRect.mBottom;
+    doc_rect.mTop = line_iter->mRect.mTop;
+
 	// set rect to 0 width
 	doc_rect.mRight = doc_rect.mLeft; 
 
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 2484790189c94882f3ff2ef9eeb32fa9b3963605..f6e5208eaa93fd97642ad60ee96476a2efd7d649 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -680,6 +680,8 @@ class LLTextBase
 public:
 	bool							hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
 
+    std::vector<LLRect> getSelctionRects();
+
 protected:
 	// text segmentation and flow
 	segment_set_t       		mSegments;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 49f98580c49918665c64b7cd2dd52c33a8042c98..c09978a3fe6633fa5543d2896974000b4f3d672b 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3176,18 +3176,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
                 {
                     LLMutexLock lock(&window_imp->mRawMouseMutex);
 
-                    S32 speed;
-                    const S32 DEFAULT_SPEED(10);
-                    SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
-                    if (speed == DEFAULT_SPEED)
+                    bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE);
+
+                    if (absolute_coordinates)
                     {
-                        window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
-                        window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
+                        static S32 prev_absolute_x = 0;
+                        static S32 prev_absolute_y = 0;
+                        S32 absolute_x;
+                        S32 absolute_y;
+
+                        if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header
+                        {
+                            // touch screen spams (0,0) coordinates in a number of situations
+                            // (0,0) might need to be filtered
+                            absolute_x = raw->data.mouse.lLastX;
+                            absolute_y = raw->data.mouse.lLastY;
+                        }
+                        else
+                        {
+                            bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP;
+
+                            S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
+                            S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
+
+                            absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width;
+                            absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height;
+                        }
+
+                        window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x;
+                        window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y;
+
+                        prev_absolute_x = absolute_x;
+                        prev_absolute_y = absolute_y;
                     }
                     else
                     {
-                        window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
-                        window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
+                        S32 speed;
+                        const S32 DEFAULT_SPEED(10);
+                        SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0);
+                        if (speed == DEFAULT_SPEED)
+                        {
+                            window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX;
+                            window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY;
+                        }
+                        else
+                        {
+                            window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
+                            window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
+                        }
                     }
                 }
             }
@@ -4323,7 +4359,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes)
 
 	if (needs_update)
 	{
-		mPreeditor->resetPreedit();
+        if (preedit_string.length() != 0 || result_string.length() != 0)
+        {
+            mPreeditor->resetPreedit();
+        }
 
 		if (result_string.length() > 0)
 		{
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ca769f76e059c70972cad692d58a74d863f0e425..ad69a1296deb3450d3b4f2b3a8519b362a6a6cda 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -331,9 +331,9 @@ set(viewer_SOURCE_FILES
     llfloaternotificationsconsole.cpp
     llfloaternotificationstabbed.cpp
     llfloateroutfitphotopreview.cpp 
-    llfloateroutfitsnapshot.cpp
     llfloaterobjectweights.cpp
     llfloateropenobject.cpp
+    llfloatersimpleoutfitsnapshot.cpp
     llfloaterpathfindingcharacters.cpp
     llfloaterpathfindingconsole.cpp
     llfloaterpathfindinglinksets.cpp
@@ -1036,9 +1036,9 @@ set(viewer_HEADER_FILES
     llfloaternotificationsconsole.h
     llfloaternotificationstabbed.h
     llfloateroutfitphotopreview.h
-    llfloateroutfitsnapshot.h
     llfloaterobjectweights.h
     llfloateropenobject.h
+    llfloatersimpleoutfitsnapshot.h
     llfloaterpathfindingcharacters.h
     llfloaterpathfindingconsole.h
     llfloaterpathfindinglinksets.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 4aa5a3a58e8c27e16189402e6ab0e13712de35f8..f5199477c52d78cde8dd8517794f43ad0e5abd47 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.8
+6.6.9
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 70bc2529bb9b49e7b4b978dff46b524e04cdbc0a..a4136aeb10e673079f46739d34d487ea7acd07c6 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5125,7 +5125,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
+      <string>https://search.[GRID]/viewer/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
     </map>
     <key>GuidebookURL</key>
     <map>
@@ -15078,6 +15078,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>MediaSoundsEarLocation</key>
+    <map>
+      <key>Comment</key>
+      <string>Location of the virtual ear for media and sounds</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>VoiceHost</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 9085a491a57ce80df5defccb245b250f64df94e4..2ec8f0dd5c326dfecff8ac6728ac31ddee8fe305 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -203,7 +203,7 @@ VARYING vec2 vary_texcoord2;
 uniform float env_intensity;
 uniform vec4 specular_color;  // specular color RGB and specular exponent (glossiness) in alpha
 
-#ifdef HAS_ALPHA_MASK
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
 uniform float minimum_alpha;
 #endif
 
@@ -228,12 +228,11 @@ void main()
     vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
 	diffcol.rgb *= vertex_color.rgb;
 
-#ifdef HAS_ALPHA_MASK
-#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND
-    if (diffcol.a*vertex_color.a < minimum_alpha)
-#else
-    if (diffcol.a < minimum_alpha)
-#endif
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+
+    // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
+    float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637)
+    if (diffcol.a < minimum_alpha-bias)
     {
         discard;
     }
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index b334a7773b6d15c1357362143ab07e4241b6c5d7..51ea47fdd003881a9e0f8ca625a1bda3863aea30 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -33,7 +33,6 @@ RenderAvatarLODFactor		1	1.0
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   16
 RenderAvatarMaxComplexity          1	350000
-RenderAvatarVP				1	1
 RenderAutoMuteSurfaceAreaLimit     1	1000.0
 RenderCubeMap				1	1
 RenderDelayVBUpdate			1	0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index ad114880095353f829cf58e29fa6f26cb6b42dcf..4587334dea29efc3aa74267917935b641d2c6c5e 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -33,7 +33,6 @@ RenderAvatarLODFactor		1	1.0
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   16
 RenderAvatarMaxComplexity          1	350000
-RenderAvatarVP				1	1
 RenderAutoMuteSurfaceAreaLimit     1	1000.0
 RenderCubeMap				1	1
 RenderDelayVBUpdate			1	0
@@ -82,7 +81,6 @@ RenderAvatarLODFactor		1	0
 RenderAvatarPhysicsLODFactor 1	0
 RenderAvatarMaxNonImpostors 1   3
 RenderAvatarMaxComplexity          1	25000
-RenderAvatarVP				1	0
 RenderFarClip				1	64
 RenderFlexTimeFactor		1	0
 RenderGlowResolutionPow		1	8
@@ -112,7 +110,6 @@ RenderAvatarLODFactor		1	0
 RenderAvatarPhysicsLODFactor 1	0
 RenderAvatarMaxNonImpostors 1   3
 RenderAvatarMaxComplexity          1	35000
-RenderAvatarVP				1	0
 RenderFarClip				1	64
 RenderFlexTimeFactor		1	0
 RenderGlowResolutionPow		1	8
@@ -141,7 +138,6 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	0.5
 RenderAvatarMaxComplexity   1	100000
 RenderAvatarPhysicsLODFactor 1	0.75
-RenderAvatarVP				1	1
 RenderFarClip				1	96
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	8
@@ -170,7 +166,6 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	200000
 RenderAvatarPhysicsLODFactor 1	1.0
-RenderAvatarVP				1	1
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -199,7 +194,6 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	250000
 RenderAvatarPhysicsLODFactor 1	1.0
-RenderAvatarVP				1	1
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	10
@@ -228,7 +222,6 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	300000
 RenderAvatarPhysicsLODFactor 1	1.0
-RenderAvatarVP				1	1
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	10
@@ -257,7 +250,6 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	350000
 RenderAvatarPhysicsLODFactor 1	1.0
-RenderAvatarVP				1	1
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	10
@@ -285,7 +277,6 @@ RenderAnisotropicLevel			1	16
 RenderAvatarCloth			1	1
 RenderAvatarLODFactor		1	1.0
 RenderAvatarPhysicsLODFactor 1	1.0
-RenderAvatarVP				1	1
 RenderFarClip				1	256
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	10
@@ -360,7 +351,6 @@ RenderCompressTextures		1	0
 // No Pixel Shaders available
 //
 list NoPixelShaders
-RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
 RenderReflectionDetail		0	0
 WindLightUseAtmosShaders	0	0
@@ -373,7 +363,6 @@ RenderShadowDetail			0	0
 // No Vertex Shaders available
 //
 list NoVertexShaders
-RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
 RenderReflectionDetail		0	0
 WindLightUseAtmosShaders	0	0
@@ -400,7 +389,6 @@ RenderAnisotropicLevel		0	0
 list safe
 RenderAnisotropicLevel			1	0
 RenderAvatarCloth			0	0
-RenderAvatarVP				0	0
 RenderAvatarMaxNonImpostors 1	16
 RenderAvatarMaxComplexity          1	80000
 RenderObjectBump			0	0
@@ -595,7 +583,6 @@ Disregard128DefaultDrawDistance	1	0
 // on various ATI chipsets on drivers before 8.2
 
 list ATIOldDriver
-RenderAvatarVP				0	0
 RenderAvatarCloth			0	0
 // Avoid driver crashes with some features on Linux with old ATI drivers
 UseOcclusion				0	0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 37d1c56907ed17941508b036207af42357973c23..aaa0fcc5a606f149abbf1cae9883270399b31d8e 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -33,7 +33,6 @@ RenderAvatarLODFactor			1	1.0
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors     1   16
 RenderAvatarMaxComplexity              1	350000
-RenderAvatarVP					1	1
 RenderAutoMuteSurfaceAreaLimit     1	1000.0
 RenderCubeMap				1	1
 RenderDelayVBUpdate			1	0
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 0562f8ee389b114fa14e6dd0320fef0e94ae89c2..380a1c38f6c8c085c93904940fefb7a2b98b1f91 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3050,9 +3050,11 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr
 
 bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
 {
-    std::string url;
-
-    url = getRegion()->getCapability(capName);
+    if (!getRegion())
+    {
+        return false;
+    }
+    std::string url = getRegion()->getCapability(capName);
 
     if (url.empty())
     {
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 9bf3831089bdcfd2f710d350e43c8c712be02b86..f938c321fd6c60a8b84a21461dd6bab5e8709ec2 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -223,7 +223,7 @@
 #include "llcommandlineparser.h"
 #include "llfloatermemleak.h"
 #include "llfloaterreg.h"
-#include "llfloateroutfitsnapshot.h"
+#include "llfloatersimpleoutfitsnapshot.h"
 #include "llfloatersnapshot.h"
 #include "llsidepanelinventory.h"
 
@@ -1285,7 +1285,6 @@ bool LLAppViewer::init()
 
     //LLSimpleton creations
     LLEnvironment::createInstance();
-    LLEnvironment::getInstance()->initSingleton();
     LLWorld::createInstance();
     LLSelectMgr::createInstance();
     LLViewerCamera::createInstance();
@@ -1533,7 +1532,7 @@ bool LLAppViewer::doFrame()
 					LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
 				pingMainloopTimeout("Main:Snapshot");
 				LLFloaterSnapshot::update(); // take snapshots
-					LLFloaterOutfitSnapshot::update();
+                LLFloaterSimpleOutfitSnapshot::update();
 				gGLActive = FALSE;
 			}
 		}
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index cbd3f6af2cc627adf98cf206f4f2612e5a89d7a1..10dac5057b9647018d104407cb2167d6218b9bdb 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -102,7 +102,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const
 
 bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
 {
-    static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
+    static LLCachedControl<S32> ear_mode(gSavedSettings, "MediaSoundsEarLocation", 0);
 
     LLVector3d pos_ear;
 
@@ -113,9 +113,6 @@ bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cu
             break;
 
         case 1: // avatar
-        case 2:
-            // voice support 'mixed' in '2' case with agent's position and camera's rotations
-            // but it is not defined in settings and uses camera as default
             pos_ear = gAgent.getPositionGlobal();
             break;
 
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 44912dc7f21ec11002f2b80fe353e09e826d4ba2..34bb09c3b9dd96c68228b11a7d606db5967d187c 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -688,10 +688,10 @@ class LLChatHistoryHeader: public LLPanel
 
 	void showInspector()
 	{
-//		if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return;
+//		if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return;
 // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
 		// Don't double-click show the inspector if we're not showing the info control
-		if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) ) return;
+		if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) ) return;
 // [/RLVa:KB]
 		
 		if (mSourceType == CHAT_SOURCE_OBJECT)
@@ -864,6 +864,7 @@ class LLChatHistoryHeader: public LLPanel
 				icon->setValue(LLSD("OBJECT_Icon"));
 				break;
 			case CHAT_SOURCE_SYSTEM:
+			case CHAT_SOURCE_REGION:
 				icon->setValue(LLSD("AL_Logo"));
 				break;
 			case CHAT_SOURCE_TELEPORT:
@@ -1063,9 +1064,9 @@ class LLChatHistoryHeader: public LLPanel
 
 	void showInfoCtrl()
 	{
-//		const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType;
+//		const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType;
 // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
-		const bool isVisible = mShowInfoCtrl && !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType;
+		const bool isVisible = mShowInfoCtrl && !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType;
 // [/RLVa:KB]
 		if (isVisible)
 		{
@@ -1479,9 +1480,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
 				prependNewLineState = false;
 			}
-//			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
+//			else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION)
 // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f
-			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && !chat.mRlvNamesFiltered)
+			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION && !chat.mRlvNamesFiltered)
 // [/RLVa:KB]
 			{
 				LLStyle::Params link_params(body_message_params);
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 0efc6907945c8d77b15000fd8ca9736b399a78b7..68f594383d00b4b7c81eabb9f409c9f13bb90dfc 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -87,7 +87,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 	virtual BOOL removeItem() { return FALSE; }
 	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
 	virtual void move( LLFolderViewModelItem* parent_listener ) { }
-	virtual BOOL isItemCopyable() const { return FALSE; }
+    virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
 // [SL:KB] - Patch: Inventory-Actions | Checked: 2013-09-19 (Catznip-3.6)
 	/*virtual*/ bool isItemLinkable() const { return false; }
 // [/SL:KB]
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 13d9ed6b4e77ad6b65e9b1e4edfd74b4e1b2bde9..7fa2c44416fd2aedfb44687e2e3fe1280f6f99b8 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -41,6 +41,7 @@
 #include "lldrawable.h"
 #include "llface.h"
 #include "llsky.h"
+#include "llstartup.h"
 #include "lltextureentry.h"
 #include "llviewercamera.h"
 #include "llviewertexturelist.h"
@@ -79,11 +80,6 @@ static S32 bump_channel = -1;
 
 #define LL_BUMPLIST_MULTITHREADED 1 // TODO -- figure out why this doesn't work
 
-// static 
-void LLStandardBumpmap::init()
-{
-	LLStandardBumpmap::restoreGL();
-}
 
 // static 
 void LLStandardBumpmap::shutdown()
@@ -94,7 +90,7 @@ void LLStandardBumpmap::shutdown()
 // static 
 void LLStandardBumpmap::restoreGL()
 {
-	addstandard();
+    addstandard();
 }
 
 // static
@@ -107,6 +103,12 @@ void LLStandardBumpmap::addstandard()
 		return ;
 	}
 
+    if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED)
+    {
+        // Not ready, need caps for images
+        return;
+    }
+
 	// can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup.  Sigh.  So clear the list every time before we (re-)add the standard bumpmaps.
 	//llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 );
 	clear();
@@ -754,8 +756,6 @@ void LLBumpImageList::init()
 	llassert( mBrightnessEntries.size() == 0 );
 	llassert( mDarknessEntries.size() == 0 );
 
-	LLStandardBumpmap::init();
-
 	LLStandardBumpmap::restoreGL();
     sMainQueue = LL::WorkQueue::getInstance("mainloop");
     sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index e8a027967bcca922e44c560f2471874a1c22bed1..cf463f4458ecc48981628764271a63204d90cbbe 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -118,7 +118,6 @@ class LLStandardBumpmap
 	static void clear();
 	static void addstandard();
 
-	static void init();
 	static void shutdown();
 	static void restoreGL();
 	static void destroyGL();
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 6002e66552987888cc4c022e4c0a5b4455b6831d..d029761e3f4b90ed724de1a317b15f406ffb947f 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -877,26 +877,37 @@ void LLEnvironment::initSingleton()
 
     requestRegion();
 
-    gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
+    if (!mParcelCallbackConnection.connected())
+    {
+        mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); });
 
-    //TODO: This frequently results in one more request than we need.  It isn't breaking, but should be nicer.
-    // We need to know new env version to fix this, without it we can only do full re-request
-    // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
-    LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
-    gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
+        //TODO: This frequently results in one more request than we need.  It isn't breaking, but should be nicer.
+        // We need to know new env version to fix this, without it we can only do full re-request
+        // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open
+        mRegionUpdateCallbackConnection = LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); });
+        mRegionChangeCallbackConnection = gAgent.addRegionChangedCallback([this]() { onRegionChange(); });
 
-    gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
+        mPositionCallbackConnection = gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); });
+    }
 
     if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT))
     {
         gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler);
     }
 
+    LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
     LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; });
 }
 
 void LLEnvironment::cleanupSingleton()
 {
+    if (mParcelCallbackConnection.connected())
+    {
+        mParcelCallbackConnection.disconnect();
+        mRegionUpdateCallbackConnection.disconnect();
+        mRegionChangeCallbackConnection.disconnect();
+        mPositionCallbackConnection.disconnect();
+    }
     LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME);
 }
 
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index e688bfec0545fde37c3d7d024184180416a9e3f4..56ba5c6d92d357e17b7a574e42f2d5f5aa4037de 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -405,6 +405,11 @@ class LLEnvironment final : public LLSimpleton<LLEnvironment>
     bool                        mShowMoonBeacon;
     S32                         mEditorCounter;
 
+    connection_t                mParcelCallbackConnection;
+    connection_t                mRegionUpdateCallbackConnection;
+    connection_t                mRegionChangeCallbackConnection;
+    connection_t                mPositionCallbackConnection;
+
     struct UpdateInfo
     {
         typedef std::shared_ptr<UpdateInfo> ptr_t;
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index 4e9a36e67de64900d5afd2dfbde4e90edc7c6e6d..44e508977a40658a5312b5301c43d702c689e18f 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -84,7 +84,7 @@ LLFloater360Capture::~LLFloater360Capture()
     // Tell the Simulator not to send us everything anymore
     // and revert to the regular "keyhole" frustum of interest
     // list updates.
-    if (gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
+    if (!LLApp::isExiting() && gSavedSettings.getBOOL("360CaptureUseInterestListCap"))
     {
         const bool send_everything = false;
         changeInterestListMode(send_everything);
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 060d0b2b66ca4f079a9cd27b05ad1bf33f39b2dc..b835e472e33ba809627e1cc2e77efbb731b68e7d 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -327,7 +327,6 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
 		restoreFloater();
 		onCollapseToLine(this);
 	}
-	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
 
 // virtual
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 04a3c7e7f13ef64906a832cac86d1bdb40830648..b3bc55dbc8ed855c63e880323168ebdf52e19556 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -992,6 +992,7 @@ void LLFloaterIMSession::updateMessages()
 			std::string from = msg["from"].asString();
 			std::string message = msg["message"].asString();
 			bool is_history = msg["is_history"].asBoolean();
+			bool is_region_msg = msg["is_region_msg"].asBoolean();
 
 			LLChat chat;
 			chat.mFromID = from_id;
@@ -999,6 +1000,10 @@ void LLFloaterIMSession::updateMessages()
 			chat.mFromName = from;
 			chat.mTimeStr = time;
 			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+            if (is_region_msg)
+            {
+                chat.mSourceType = CHAT_SOURCE_REGION;
+            }
 
 			// process offer notification
 			if (msg.has("notification_id"))
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d514d46ae8006761f032ca676c02311d8b14730c..efcc411fdc188e0a55cacaf8fd4057edcdee8e07 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -254,7 +254,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mGearBtn = getChild<LLButton>("gear_btn");
     mAddBtn = getChild<LLButton>("add_btn");
 	mVoiceButton = getChild<LLButton>("voice_call_btn");
-    mTranslationCheckBox = getChild<LLUICtrl>("translate_chat_checkbox_lp");
     
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 	mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
@@ -813,8 +812,6 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 	mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
 
 	enableDisableCallBtn();
-
-	showTranslationCheckbox();
 }
  
 void LLFloaterIMSessionTab::forceReshape()
@@ -831,11 +828,6 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
 	mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE);
 }
 
-void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
-{
-	mTranslationCheckBox->setVisible(mIsNearbyChat && show);
-}
-
 // static
 void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
 {
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 484b921021df22888edf87fced731b0fceae5710..eba7298ff200e5e345a00e2866c057c573ca1b45 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -71,8 +71,6 @@ class LLFloaterIMSessionTab
     static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
     static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
 
-	// show/hide the translation check box
-	void showTranslationCheckbox(const BOOL visible = FALSE);
 
 	bool isNearbyChat() {return mIsNearbyChat;}
 
@@ -193,7 +191,6 @@ class LLFloaterIMSessionTab
 // [SL:KB] - Patch: Chat-Misc | Checked: 2014-03-22 (Catznip-3.6)
 	LLPanel* mExtendedButtonPanel = nullptr;
 // [/SL:KB]
-    LLUICtrl* mTranslationCheckBox;
 
 private:
 	// Handling selection and contextual menu
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
deleted file mode 100644
index 06709922c6623f35cca0b70812e7a4feaaf52b81..0000000000000000000000000000000000000000
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/** 
- * @file llfloateroutfitsnapshot.cpp
- * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2016, 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 "llfloatersnapshot.h"
-#include "llfloateroutfitsnapshot.h"
-
-#include "llagent.h"
-#include "llfloaterreg.h"
-#include "llimagefiltersmanager.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llpostcard.h"
-#include "llresmgr.h"		// LLLocale
-#include "llsdserialize.h"
-#include "llsidetraypanelcontainer.h"
-#include "llspinctrl.h"
-#include "llviewercontrol.h"
-#include "lltoolfocus.h"
-#include "lltoolmgr.h"
-
-///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
-
-const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
-const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
-
-static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
-
-///----------------------------------------------------------------------------
-/// Class LLFloaterOutfitSnapshot::Impl
-///----------------------------------------------------------------------------
-
-// virtual
-LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
-{
-    LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
-    LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel);
-    if (!ok_if_not_found)
-    {
-        llassert_always(active_panel != NULL);
-    }
-    return active_panel;
-}
-
-// virtual
-LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
-{
-    return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
-}
-
-// virtual
-LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
-{
-    return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
-}
-
-// This is the main function that keeps all the GUI controls in sync with the saved settings.
-// It should be called anytime a setting is changed that could affect the controls.
-// No other methods should be changing any of the controls directly except for helpers called by this method.
-// The basic pattern for programmatically changing the GUI settings is to first set the
-// appropriate saved settings and then call this method to sync the GUI with them.
-// FIXME: The above comment seems obsolete now.
-// virtual
-void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
-{
-    LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater);
-    LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
-    LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater);
-
-    LLSnapshotLivePreview* previewp = getPreviewView();
-    BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
-    // *TODO: Separate maximum size for Web images from postcards
-    LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
-    LLLocale locale(LLLocale::USER_LOCALE);
-    std::string bytes_string;
-    if (got_snap)
-    {
-        LLResMgr::getIntegerString(bytes_string, (previewp->getDataSize()) >> 10);
-    }
-
-    // Update displayed image resolution.
-    LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
-    image_res_tb->setVisible(got_snap);
-    if (got_snap)
-    {
-        image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
-        image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
-    }
-
-    floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
-    floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor"));
-
-    updateResolution(floater);
-
-    if (previewp)
-    {
-        previewp->setSnapshotType(shot_type);
-        previewp->setSnapshotFormat(shot_format);
-        previewp->setSnapshotBufferType(layer_type);
-    }
-
-    LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
-    if (current_panel)
-    {
-        LLSD info;
-        info["have-snapshot"] = got_snap;
-        current_panel->updateControls(info);
-    }
-    LL_DEBUGS() << "finished updating controls" << LL_ENDL;
-}
-
-// virtual
-std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix()
-{
-    return "panel_outfit_snapshot_";
-}
-
-// Show/hide upload status message.
-// virtual
-void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg)
-{
-    mFloater->setSuccessLabelPanelVisible(finished && ok);
-    mFloater->setFailureLabelPanelVisible(finished && !ok);
-
-    if (finished)
-    {
-        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);
-
-        LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
-        snapshot_panel->onOpen(LLSD());
-    }
-}
-
-void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
-{
-    LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-
-    if (!view)
-    {
-        llassert(view);
-        return;
-    }
-
-    S32 width = OUTFIT_SNAPSHOT_WIDTH;
-    S32 height = OUTFIT_SNAPSHOT_HEIGHT;
-
-    LLSnapshotLivePreview* previewp = getPreviewView();
-    if (previewp)
-    {
-        S32 original_width = 0, original_height = 0;
-        previewp->getSize(original_width, original_height);
-
-        if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
-        { //clamp snapshot resolution to window size when showing UI or HUD in snapshot
-            width = llmin(width, gViewerWindow->getWindowWidthRaw());
-            height = llmin(height, gViewerWindow->getWindowHeightRaw());
-        }
-
-
-        llassert(width > 0 && height > 0);
-
-        // use the resolution from the selected pre-canned drop-down choice
-        LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
-        previewp->setSize(width, height);
-
-        if (original_width != width || original_height != height)
-        {
-            // hide old preview as the aspect ratio could be wrong
-            checkAutoSnapshot(previewp, FALSE);
-            LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
-            previewp->updateSnapshot(TRUE);
-        }
-    }
-}
-
-///----------------------------------------------------------------------------
-/// Class LLFloaterOutfitSnapshot
-///----------------------------------------------------------------------------
-
-// Default constructor
-LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key)
-: LLFloaterSnapshotBase(key),
-mOutfitGallery(NULL)
-{
-    impl = new Impl(this);
-}
-
-LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot()
-{
-}
-
-// virtual
-BOOL LLFloaterOutfitSnapshot::postBuild()
-{
-    mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
-    childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
-    mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
-    mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
-    mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
-
-    childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
-    getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
-
-    childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
-    getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
-
-    getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
-    childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
-
-    getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
-    childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
-
-    getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
-    getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
-
-    // Filters
-    LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
-    std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
-    for (U32 i = 0; i < filter_list.size(); i++)
-    {
-        filterbox->add(filter_list[i]);
-    }
-    childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
-
-    mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
-
-    // create preview window
-    LLRect full_screen_rect = getRootView()->getRect();
-    LLSnapshotLivePreview::Params p;
-    p.rect(full_screen_rect);
-    LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
-    LLView* parent_view = gSnapshotFloaterView->getParent();
-
-    parent_view->removeChild(gSnapshotFloaterView);
-    // make sure preview is below snapshot floater
-    parent_view->addChild(previewp);
-    parent_view->addChild(gSnapshotFloaterView);
-
-    //move snapshot floater to special purpose snapshotfloaterview
-    gFloaterView->removeChild(this);
-    gSnapshotFloaterView->addChild(this);
-
-    impl->mPreviewHandle = previewp->getHandle();
-    previewp->setContainer(this);
-    impl->updateControls(this);
-    impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
-    impl->updateLayout(this);
-
-    previewp->mKeepAspectRatio = FALSE;
-    previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
-
-    return TRUE;
-}
-
-// virtual
-void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
-{
-    LLSnapshotLivePreview* preview = getPreviewView();
-    if (preview)
-    {
-        LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
-        preview->updateSnapshot(TRUE);
-    }
-    focusFirstItem(FALSE);
-    gSnapshotFloaterView->setEnabled(TRUE);
-    gSnapshotFloaterView->setVisible(TRUE);
-    gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
-
-    impl->updateControls(this);
-    impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
-    impl->updateLayout(this);
-
-    LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
-    snapshot_panel->onOpen(LLSD());
-    postPanelSwitch();
-
-}
-
-void LLFloaterOutfitSnapshot::onExtendFloater()
-{
-	impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
-}
-
-// static 
-void LLFloaterOutfitSnapshot::update()
-{
-    LLFloaterOutfitSnapshot* inst = findInstance();
-    if (inst != NULL)
-    {
-        inst->impl->updateLivePreview();
-    }
-}
-
-
-// static
-LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
-{
-    return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
-}
-
-// static
-LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
-{
-    return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
-}
-
-// virtual
-void LLFloaterOutfitSnapshot::saveTexture()
-{
-    LL_DEBUGS() << "saveTexture" << LL_ENDL;
-
-    LLSnapshotLivePreview* previewp = getPreviewView();
-    if (!previewp)
-    {
-        llassert(previewp != NULL);
-        return;
-    }
-
-    if (mOutfitGallery)
-    {
-        mOutfitGallery->onBeforeOutfitSnapshotSave();
-    }
-    previewp->saveTexture(TRUE, getOutfitID().asString());
-    if (mOutfitGallery)
-    {
-        mOutfitGallery->onAfterOutfitSnapshotSave();
-    }
-    closeFloater();
-}
-
-///----------------------------------------------------------------------------
-/// Class LLOutfitSnapshotFloaterView
-///----------------------------------------------------------------------------
-
-LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
-{
-}
-
-LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView()
-{
-}
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
deleted file mode 100644
index c22bf85826edc11c26d3720a7137ea2c796e8842..0000000000000000000000000000000000000000
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * @file llfloateroutfitsnapshot.h
- * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2016, 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_LLFLOATEROUTFITSNAPSHOT_H
-#define LL_LLFLOATEROUTFITSNAPSHOT_H
-
-#include "llfloater.h"
-#include "llfloatersnapshot.h"
-#include "lloutfitgallery.h"
-#include "llsnapshotlivepreview.h"
-
-///----------------------------------------------------------------------------
-/// Class LLFloaterOutfitSnapshot
-///----------------------------------------------------------------------------
-
-class LLFloaterOutfitSnapshot final : public LLFloaterSnapshotBase
-{
-    LOG_CLASS(LLFloaterOutfitSnapshot);
-
-public:
-
-    LLFloaterOutfitSnapshot(const LLSD& key);
-    /*virtual*/ ~LLFloaterOutfitSnapshot();
-
-    /*virtual*/ BOOL postBuild();
-    /*virtual*/ void onOpen(const LLSD& key);
-
-    static void update();
-
-    void onExtendFloater();
-
-    static LLFloaterOutfitSnapshot* getInstance();
-    static LLFloaterOutfitSnapshot* findInstance();
-    /*virtual*/ void saveTexture();
-
-    const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
-
-    void setOutfitID(LLUUID id) { mOutfitID = id; }
-    LLUUID getOutfitID() { return mOutfitID; }
-    void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
-
-    class Impl;
-    friend class Impl;
-private:
-
-    LLUUID mOutfitID;
-    LLOutfitGallery* mOutfitGallery;
-};
-
-///----------------------------------------------------------------------------
-/// Class LLFloaterOutfitSnapshot::Impl
-///----------------------------------------------------------------------------
-
-class LLFloaterOutfitSnapshot::Impl final : public LLFloaterSnapshotBase::ImplBase
-{
-    LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
-public:
-    Impl(LLFloaterSnapshotBase* floater)
-        : LLFloaterSnapshotBase::ImplBase(floater)
-    {}
-    ~Impl()
-    {}
-    void updateResolution(void* data);
-
-    static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
-
-    /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
-    /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
-    /*virtual*/ std::string getSnapshotPanelPrefix();
-
-    /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
-
-private:
-    /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
-    /*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
-};
-
-///----------------------------------------------------------------------------
-/// Class LLOutfitSnapshotFloaterView
-///----------------------------------------------------------------------------
-
-class LLOutfitSnapshotFloaterView final : public LLFloaterView
-{
-public:
-    struct Params
-        : public LLInitParam::Block<Params, LLFloaterView::Params>
-    {
-    };
-
-protected:
-    LLOutfitSnapshotFloaterView(const Params& p);
-    friend class LLUICtrlFactory;
-
-public:
-    virtual ~LLOutfitSnapshotFloaterView();
-};
-
-extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
-
-#endif // LL_LLFLOATEROUTFITSNAPSHOT_H
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 4d36dddfce71f9da9c713397ec8ba72e03dfab93..1064d0c7e3dbca5f23b572a2f1edeeb5e497b579 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -919,6 +919,7 @@ void LLFloaterPreference::saveSettings()
 		if (panel)
 			panel->saveSettings();
 	}
+    saveIgnoredNotifications();
 }	
 
 void LLFloaterPreference::apply()
@@ -1036,6 +1037,8 @@ void LLFloaterPreference::cancel()
 		gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset);
 		LLPresetsManager::getInstance()->triggerChangeSignal();
 	}
+
+    restoreIgnoredNotifications();
 }
 
 void LLFloaterPreference::onOpen(const LLSD& key)
@@ -1936,6 +1939,10 @@ void LLFloaterPreference::onClickEnablePopup()
 	}
 	
 	buildPopupLists();
+    if (!mFilterEdit->getText().empty())
+    {
+        filterIgnorableNotifications();
+    }
 }
 
 void LLFloaterPreference::onClickDisablePopup()
@@ -1951,6 +1958,10 @@ void LLFloaterPreference::onClickDisablePopup()
 	}
 	
 	buildPopupLists();
+    if (!mFilterEdit->getText().empty())
+    {
+        filterIgnorableNotifications();
+    }
 }
 
 void LLFloaterPreference::resetAllIgnored()
@@ -3999,11 +4010,24 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force)
 		return;
 
 	mSearchData->mRootTab->hightlightAndHide( seachValue );
+    filterIgnorableNotifications();
+
 	LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
 	if( pRoot )
 		pRoot->selectFirstTab();
 }
 
+void LLFloaterPreference::filterIgnorableNotifications()
+{
+    bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue());
+    visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue());
+
+    if (visible)
+    {
+        getChildRef<LLTabContainer>("pref core").setTabVisibility( getChild<LLPanel>("msgs"), true );
+    }
+}
+
 void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer )
 {
 	if( !aView )
@@ -4092,3 +4116,28 @@ void LLFloaterPreference::collectSearchableItems()
 	}
 	mSearchDataDirty = false;
 }
+
+void LLFloaterPreference::saveIgnoredNotifications()
+{
+    for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin();
+            iter != LLNotifications::instance().templatesEnd();
+            ++iter)
+    {
+        LLNotificationTemplatePtr templatep = iter->second;
+        LLNotificationFormPtr formp = templatep->mForm;
+
+        LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
+        if (ignore <= LLNotificationForm::IGNORE_NO)
+            continue;
+
+        mIgnorableNotifs[templatep->mName] = !formp->getIgnored();
+    }
+}
+
+void LLFloaterPreference::restoreIgnoredNotifications()
+{
+    for (std::map<std::string, bool>::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it)
+    {
+        LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second);
+    }
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 643d5375600b3fec2893fbbfcb8e6a252431c045..43c9ef0c0753a5273c1880792eb29dd4ced1661e 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -144,6 +144,9 @@ class LLFloaterPreference final : public LLFloater, public LLAvatarPropertiesObs
 	// cancel() can restore them.	
 	void saveSettings();
 
+	void saveIgnoredNotifications();
+	void restoreIgnoredNotifications();
+
 	void setCacheLocation(const LLStringExplicit& location);
 
 	void onClickSetCache();
@@ -248,6 +251,9 @@ class LLFloaterPreference final : public LLFloater, public LLAvatarPropertiesObs
 
 	void onUpdateFilterTerm( bool force = false );
 	void collectSearchableItems();
+    void filterIgnorableNotifications();
+
+    std::map<std::string, bool> mIgnorableNotifs;
 };
 
 class LLPanelPreference : public LLPanel
diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bab2efbbd56aa0fb59c516223b08922a49cef42d
--- /dev/null
+++ b/indra/newview/llfloatersimpleoutfitsnapshot.cpp
@@ -0,0 +1,333 @@
+/** 
+* @file llfloatersimpleoutfitsnapshot.cpp
+* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
+*
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2022, 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 "llfloatersimpleoutfitsnapshot.h"
+
+#include "llfloaterreg.h"
+#include "llimagefiltersmanager.h"
+#include "llstatusbar.h" // can_afford_transaction()
+#include "llnotificationsutil.h"
+#include "llagentbenefits.h"
+#include "llviewercontrol.h"
+
+LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL;
+
+const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
+const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
+
+static LLDefaultChildRegistry::Register<LLSimpleOutfitSnapshotFloaterView> r("simple_snapshot_outfit_floater_view");
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSimpleOutfitSnapshot::Impl
+///----------------------------------------------------------------------------
+
+LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
+{
+    return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
+}
+
+LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
+{
+    return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
+}
+
+void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
+{
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    updateResolution(floater);
+    if (previewp)
+    {
+        previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE);
+        previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG);
+        previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR);
+    }
+}
+
+std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix()
+{
+    return "panel_outfit_snapshot_";
+}
+
+void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data)
+{
+    LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data;
+
+    if (!view)
+    {
+        llassert(view);
+        return;
+    }
+
+    S32 width = OUTFIT_SNAPSHOT_WIDTH;
+    S32 height = OUTFIT_SNAPSHOT_HEIGHT;
+
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    if (previewp)
+    {
+        S32 original_width = 0, original_height = 0;
+        previewp->getSize(original_width, original_height);
+
+        if (gSavedSettings.getBOOL("RenderHUDInSnapshot"))
+        { //clamp snapshot resolution to window size when showing UI HUD in snapshot
+            width = llmin(width, gViewerWindow->getWindowWidthRaw());
+            height = llmin(height, gViewerWindow->getWindowHeightRaw());
+        }
+
+        llassert(width > 0 && height > 0);
+
+        previewp->setSize(width, height);
+
+        if (original_width != width || original_height != height)
+        {
+            // hide old preview as the aspect ratio could be wrong
+            checkAutoSnapshot(previewp, FALSE);
+            previewp->updateSnapshot(TRUE);
+        }
+    }
+}
+
+void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
+{
+    switch (status)
+    {
+    case STATUS_READY:
+        mFloater->setCtrlsEnabled(true);
+        break;
+    case STATUS_WORKING:
+        mFloater->setCtrlsEnabled(false);
+        break;
+    case STATUS_FINISHED:
+        mFloater->setCtrlsEnabled(true);
+        break;
+    }
+
+    mStatus = status;
+}
+
+///----------------------------------------------------------------re------------
+/// Class LLFloaterSimpleOutfitSnapshot
+///----------------------------------------------------------------------------
+
+LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key)
+    : LLFloaterSnapshotBase(key),
+    mOutfitGallery(NULL)
+{
+    impl = new Impl(this);
+}
+
+LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot()
+{
+}
+
+BOOL LLFloaterSimpleOutfitSnapshot::postBuild()
+{
+    getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost()));
+
+    childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
+    childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this));
+    childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this));
+
+    mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+
+    // create preview window
+    LLRect full_screen_rect = getRootView()->getRect();
+    LLSnapshotLivePreview::Params p;
+    p.rect(full_screen_rect);
+    LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+    LLView* parent_view = gSnapshotFloaterView->getParent();
+
+    parent_view->removeChild(gSnapshotFloaterView);
+    // make sure preview is below snapshot floater
+    parent_view->addChild(previewp);
+    parent_view->addChild(gSnapshotFloaterView);
+
+    //move snapshot floater to special purpose snapshotfloaterview
+    gFloaterView->removeChild(this);
+    gSnapshotFloaterView->addChild(this);
+
+    impl->mPreviewHandle = previewp->getHandle();
+    previewp->setContainer(this);
+    impl->updateControls(this);
+    impl->setAdvanced(true);
+    impl->setSkipReshaping(true);
+
+    previewp->mKeepAspectRatio = FALSE;
+    previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
+    previewp->setAllowRenderUI(false);
+
+    return TRUE;
+}
+const S32 PREVIEW_OFFSET_X = 12;
+const S32 PREVIEW_OFFSET_Y = 70;
+
+void LLFloaterSimpleOutfitSnapshot::draw()
+{
+    LLSnapshotLivePreview* previewp = getPreviewView();
+
+    if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
+    {
+        // don't render snapshot window in snapshot, even if "show ui" is turned on
+        return;
+    }
+
+    LLFloater::draw();
+
+    if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible())
+    {		
+        if(previewp->getThumbnailImage())
+        {
+            bool working = impl->getStatus() == ImplBase::STATUS_WORKING;
+            const LLRect& thumbnail_rect = getThumbnailPlaceholderRect();
+            const S32 thumbnail_w = previewp->getThumbnailWidth();
+            const S32 thumbnail_h = previewp->getThumbnailHeight();
+
+            S32 offset_x = PREVIEW_OFFSET_X;
+            S32 offset_y = PREVIEW_OFFSET_Y;
+
+            gGL.matrixMode(LLRender::MM_MODELVIEW);
+            // Apply floater transparency to the texture unless the floater is focused.
+            F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+            LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
+            gl_draw_scaled_image(offset_x, offset_y, 
+                thumbnail_w, thumbnail_h,
+                previewp->getThumbnailImage(), color % alpha);
+#if LL_DARWIN
+            std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2";
+#else
+            std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray";
+#endif
+
+            previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color));
+
+            gGL.pushUIMatrix();
+            LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom);
+            mThumbnailPlaceholder->draw();
+            gGL.popUIMatrix();
+        }
+    }
+    impl->updateLayout(this);
+}
+
+void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key)
+{
+    LLSnapshotLivePreview* preview = getPreviewView();
+    if (preview)
+    {
+        preview->updateSnapshot(TRUE);
+    }
+    focusFirstItem(FALSE);
+    gSnapshotFloaterView->setEnabled(TRUE);
+    gSnapshotFloaterView->setVisible(TRUE);
+    gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
+
+    impl->updateControls(this);
+    impl->setStatus(ImplBase::STATUS_READY);
+}
+
+void LLFloaterSimpleOutfitSnapshot::onCancel()
+{
+    closeFloater();
+}
+
+void LLFloaterSimpleOutfitSnapshot::onSend()
+{
+    S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+    if (can_afford_transaction(expected_upload_cost))
+    {
+        saveTexture();
+        postSave();
+    }
+    else
+    {
+        LLSD args;
+        args["COST"] = llformat("%d", expected_upload_cost);
+        LLNotificationsUtil::add("ErrorPhotoCannotAfford", args);
+        inventorySaveFailed();
+    }
+}
+
+void LLFloaterSimpleOutfitSnapshot::postSave()
+{
+    impl->setStatus(ImplBase::STATUS_WORKING);
+}
+
+// static 
+void LLFloaterSimpleOutfitSnapshot::update()
+{
+    LLFloaterSimpleOutfitSnapshot* inst = findInstance();
+    if (inst != NULL)
+    {
+        inst->impl->updateLivePreview();
+    }
+}
+
+
+// static
+LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance()
+{
+    return LLFloaterReg::findTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
+}
+
+// static
+LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance()
+{
+    return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
+}
+
+void LLFloaterSimpleOutfitSnapshot::saveTexture()
+{
+     LLSnapshotLivePreview* previewp = getPreviewView();
+    if (!previewp)
+    {
+        llassert(previewp != NULL);
+        return;
+    }
+
+    if (mOutfitGallery)
+    {
+        mOutfitGallery->onBeforeOutfitSnapshotSave();
+    }
+    previewp->saveTexture(TRUE, getOutfitID().asString());
+    if (mOutfitGallery)
+    {
+        mOutfitGallery->onAfterOutfitSnapshotSave();
+    }
+    closeFloater();
+}
+
+///----------------------------------------------------------------------------
+/// Class LLSimpleOutfitSnapshotFloaterView
+///----------------------------------------------------------------------------
+
+LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
+{
+}
+
+LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView()
+{
+}
diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.h b/indra/newview/llfloatersimpleoutfitsnapshot.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc9a6c5d1e4016ef57382321ce743b09ddff1f96
--- /dev/null
+++ b/indra/newview/llfloatersimpleoutfitsnapshot.h
@@ -0,0 +1,129 @@
+/**
+* @file llfloatersimpleoutfitsnapshot.h
+* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
+*
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2022, 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_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
+#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
+
+#include "llfloater.h"
+#include "llfloatersnapshot.h"
+#include "lloutfitgallery.h"
+#include "llsnapshotlivepreview.h"
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSimpleOutfitSnapshot
+///----------------------------------------------------------------------------
+
+class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase
+{
+    LOG_CLASS(LLFloaterSimpleOutfitSnapshot);
+
+public:
+
+    LLFloaterSimpleOutfitSnapshot(const LLSD& key);
+    ~LLFloaterSimpleOutfitSnapshot();
+
+    BOOL postBuild();
+    void onOpen(const LLSD& key);
+    void draw();
+
+    static void update();
+
+    static LLFloaterSimpleOutfitSnapshot* getInstance();
+    static LLFloaterSimpleOutfitSnapshot* findInstance();
+    void saveTexture();
+
+    const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
+
+    void setOutfitID(LLUUID id) { mOutfitID = id; }
+    LLUUID getOutfitID() { return mOutfitID; }
+    void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
+
+    void postSave();
+
+    class Impl;
+    friend class Impl;
+
+private:
+    void onSend();
+    void onCancel();
+
+    LLUUID mOutfitID;
+    LLOutfitGallery* mOutfitGallery;
+};
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSimpleOutfitSnapshot::Impl
+///----------------------------------------------------------------------------
+
+class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
+{
+    LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl);
+public:
+    Impl(LLFloaterSnapshotBase* floater)
+        : LLFloaterSnapshotBase::ImplBase(floater)
+    {}
+    ~Impl()
+    {}
+    void updateResolution(void* data);
+
+    static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
+
+    LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) { return NULL; }
+    LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
+    std::string getSnapshotPanelPrefix();
+
+    void updateControls(LLFloaterSnapshotBase* floater);
+
+    void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
+
+private:
+    LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
+    void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) {};
+};
+
+///----------------------------------------------------------------------------
+/// Class LLSimpleOutfitSnapshotFloaterView
+///----------------------------------------------------------------------------
+
+class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView
+{
+public:
+    struct Params
+        : public LLInitParam::Block<Params, LLFloaterView::Params>
+    {
+    };
+
+protected:
+    LLSimpleOutfitSnapshotFloaterView(const Params& p);
+    friend class LLUICtrlFactory;
+
+public:
+    virtual ~LLSimpleOutfitSnapshotFloaterView();
+};
+
+extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView;
+
+#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index e486f18148dd66bbfae99b865a8635546e3b4527..67ce8c64de377fa0af6109aea6f5d811218da069 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -179,16 +179,20 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate
 
 	LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder");
 	thumbnail_placeholder->setVisible(mAdvanced);
-	thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
+
 	floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced);
 	floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced);
     if (floaterp->hasChild("360_label", TRUE))
     { 
         floaterp->getChild<LLUICtrl>("360_label")->setVisible(mAdvanced);
     }
-	if(!floaterp->isMinimized())
+	if (!mSkipReshaping)
 	{
-		floaterp->reshape(floater_width, floaterp->getRect().getHeight());
+        thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
+        if (!floaterp->isMinimized())
+        {
+            floaterp->reshape(floater_width, floaterp->getRect().getHeight());
+        }
 	}
 
 	bool use_freeze_frame = floaterp->getChild<LLUICtrl>("freeze_frame_check")->getValue().asBoolean();
@@ -1196,7 +1200,7 @@ S32 LLFloaterSnapshotBase::notify(const LLSD& info)
 
 		// The refresh button is initially hidden. We show it after the first update,
 		// i.e. when preview appears.
-		if (!mRefreshBtn->getVisible())
+		if (mRefreshBtn && !mRefreshBtn->getVisible())
 		{
 			mRefreshBtn->setVisible(true);
 		}
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 651c4920a7d44c7009ca7e6db36dfaaa830445de..efc711758ca16d257b5329b7cec93bbeba457ac1 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -59,9 +59,9 @@ class LLFloaterSnapshotBase : public LLFloater
 
 	const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
 
-	void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); }
-	void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); }
-	void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); }
+	void setRefreshLabelVisible(bool value) { if (mRefreshLabel) mRefreshLabel->setVisible(value); }
+	void setSuccessLabelPanelVisible(bool value) { if (mSucceessLblPanel) mSucceessLblPanel->setVisible(value); }
+	void setFailureLabelPanelVisible(bool value) { if (mFailureLblPanel) mFailureLblPanel->setVisible(value); }
 	void inventorySaveFailed();
 
 	class ImplBase;
@@ -88,6 +88,7 @@ class LLFloaterSnapshotBase::ImplBase
 		mLastToolset(NULL),
 		mAspectRatioCheckOff(false),
 		mNeedRefresh(false),
+        mSkipReshaping(false),
 		mStatus(STATUS_READY),
 		mFloater(floater)
 	{}
@@ -120,6 +121,7 @@ class LLFloaterSnapshotBase::ImplBase
 	static BOOL updatePreviewList(bool initialized);
 
 	void setAdvanced(bool advanced) { mAdvanced = advanced; }
+    void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
 
 	virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
 	virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
@@ -135,6 +137,7 @@ class LLFloaterSnapshotBase::ImplBase
 	bool mAspectRatioCheckOff;
 	bool mNeedRefresh;
 	bool mAdvanced;
+    bool mSkipReshaping;
 	EStatus mStatus;
 };
 
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index b1316e386df0ccb4262ac30409560dff2297c644..082bb888b1fa444003fba5901002131bc84cba64 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -289,7 +289,6 @@ void LLFloaterTranslationSettings::onBtnOK()
 	gSavedSettings.setString("TranslationService", getSelectedService());
 	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
 	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
-	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
-			showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+
 	closeFloater(false);
 }
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index f76f8ea22e6227b2f0354dfbfa2f6f0f8c3fc007..ae5c5e9b550e13d56fc33be60f1744bdd38fdb15 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -181,8 +181,7 @@ class LLFetchGroupMemberData : public LLGroupMgrObserver
 	virtual void processGroupData() = 0;
 protected:
 	LLUUID mGroupId;
-private:
-	bool mRequestProcessed;
+    bool mRequestProcessed;
 };
 
 class LLFetchLeaveGroupData: public LLFetchGroupMemberData
@@ -195,6 +194,22 @@ class LLFetchLeaveGroupData: public LLFetchGroupMemberData
 	 {
 		 LLGroupActions::processLeaveGroupDataResponse(mGroupId);
 	 }
+     void changed(LLGroupChange gc)
+     {
+         if (gc == GC_PROPERTIES && !mRequestProcessed)
+         {
+             LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId);
+             if (!gdatap)
+             {
+                 LL_WARNS() << "GroupData was NULL" << LL_ENDL;
+             } 
+             else
+             {
+                 processGroupData();
+                 mRequestProcessed = true;
+             }
+         }
+     }
 };
 
 LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 9c8d5f38a44e7683096f6e5df90d7c2accc1bad6..87f125a4612ff6fe825992df8f3ee3403f16fd2f 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -55,6 +55,7 @@
 #include "llviewerwindow.h"
 #include "llviewerregion.h"
 #include "llvoavatarself.h"
+#include "llworld.h"
 // [RLVa:KB] - Checked: 2010-03-09 (RLVa-1.2.0a)
 #include "rlvactions.h"
 #include "rlvhelper.h"
@@ -583,8 +584,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                     dialog,
                     parent_estate_id,
                     region_id,
-                    position,
-                    true);
+                    position);
 
                 if (!gIMMgr->isDNDMessageSend(session_id))
                 {
@@ -646,6 +646,15 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
 
                 if (!mute_im)
                 {
+                    bool region_message = false;
+                    if (region_id.isNull())
+                    {
+                        LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(from_id);
+                        if (regionp)
+                        {
+                            region_message = true;
+                        }
+                    }
                     gIMMgr->addMessage(
                         session_id,
                         from_id,
@@ -657,7 +666,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                         parent_estate_id,
                         region_id,
                         position,
-                        true);
+                        region_message);
                 }
                 else
                 {
@@ -1242,8 +1251,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                     IM_SESSION_INVITE,
                     parent_estate_id,
                     region_id,
-                    position,
-                    true);
+                    position);
             }
             else
             {
@@ -1268,8 +1276,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                     IM_SESSION_INVITE,
                     parent_estate_id,
                     region_id,
-                    position,
-                    true);
+                    position);
             }
             break;
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c03c8658654e20cd204d2f54e557995505a1de41..f78d71ea2a1cdbbe5010272bc73815ca5c5c9b66 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -772,7 +772,7 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_
 }
 
 void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, 
-	const std::string& time, const bool is_history, const LLSD& bonus)
+	const std::string& time, const bool is_history, bool is_region_msg, const LLSD& bonus)
 {
 	LLSD message;
 	message["from"] = from;
@@ -781,6 +781,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
 	message["time"] = time; 
 	message["index"] = (LLSD::Integer)mMsgs.size(); 
 	message["is_history"] = is_history;
+	message["is_region_msg"] = is_region_msg;
     message["is_announcement"] = bonus.has("announcement");
 
 	mMsgs.push_front(message); 
@@ -1146,7 +1147,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
 	mNoUnreadMsgsSignal(arg);
 }
 
-bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const LLSD& bonus) {
+bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg, const LLSD& bonus) {
 	
 	LLIMSession* session = findIMSession(session_id);
 
@@ -1156,7 +1157,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 		return false;
 	}
 
-	session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), bonus); //might want to add date separately
+	session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg, bonus); //might want to add date separately
 
 	return true;
 }
@@ -1194,9 +1195,9 @@ bool LLIMModel::proccessOnlineOfflineNotification(
 }
 
 bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
-						   const std::string& utf8_text, bool log2file /* = true */, const LLSD& bonus) { 
+						   const std::string& utf8_text, bool log2file, bool is_region_msg, const LLSD& bonus) { 
 
-	LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, bonus);
+	LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg, bonus);
 	if (!session) return false;
 
 	//good place to add some1 to recent list
@@ -1221,7 +1222,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
 }
 
 LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
-													 const std::string& utf8_text, bool log2file /* = true */, const LLSD& bonus)
+													 const std::string& utf8_text, bool log2file, bool is_region_msg, const LLSD& bonus)
 {
 	LLIMSession* session = findIMSession(session_id);
 
@@ -1237,7 +1238,7 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id,
 		from_name = SYSTEM_FROM;
 	}
 
-	addToHistory(session_id, from_name, from_id, utf8_text, bonus);
+	addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg, bonus);
 	if (log2file)
 	{
 		logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text);
@@ -2704,7 +2705,7 @@ void LLIMMgr::addMessage(
 	U32 parent_estate_id,
 	const LLUUID& region_id,
 	const LLVector3& position,
-	bool link_name, // If this is true, then we insert the name and link it to a profile
+	bool is_region_msg,
 	const LLSD& bonus)
 {
 	LLUUID other_participant_id = target_id;
@@ -2777,7 +2778,7 @@ void LLIMMgr::addMessage(
 				//<< "*** region_id: " << region_id << std::endl
 				//<< "*** position: " << position << std::endl;
 
-				LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
+				LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str(), true, is_region_msg);
 			}
 
 //			// Logically it would make more sense to reject the session sooner, in another area of the
@@ -2811,7 +2812,7 @@ void LLIMMgr::addMessage(
 	if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat))
 // [/SL:KB]
 	{
-		LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, bonus);
+		LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg, bonus);
 	}
 
 	// Open conversation floater if offline messages are present
@@ -3884,8 +3885,7 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 				IM_SESSION_INVITE,
 				message_params["parent_estate_id"].asInteger(),
 				message_params["region_id"].asUUID(),
-				ll_vector3_from_sd(message_params["position"]),
-				true);
+				ll_vector3_from_sd(message_params["position"]));
 
 			if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat))
 			{
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index de72e7a256ce939350c6225459ad01e4b9474d62..a415caf6c03134f1cb7997df24fd7ff7bcb168e0 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -91,7 +91,7 @@ class LLIMModel final :  public LLSingleton<LLIMModel>
 
 		void sessionInitReplyReceived(const LLUUID& new_session_id);
 		void addMessagesFromHistory(const std::list<LLSD>& history);
-        void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, const LLSD& bonus = LLSD());
+		void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false, const LLSD& bonus = LLSD());
 		void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
 		
 		/** @deprecated */
@@ -226,13 +226,13 @@ class LLIMModel final :  public LLSingleton<LLIMModel>
 	 * and also saved into a file if log2file is specified.
 	 * It sends new message signal for each added message.
 	 */
-	bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, const LLSD& bonus = LLSD());
+	bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, const LLSD& bonus = LLSD());
 
 	/**
 	 * Similar to addMessage(...) above but won't send a signal about a new message added
 	 */
 	LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
-		const std::string& utf8_text, bool log2file = true, const LLSD& bonus = LLSD());
+		const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, const LLSD& bonus = LLSD());
 
 	/**
 	 * Add a system message to an IM Model
@@ -310,7 +310,7 @@ class LLIMModel final :  public LLSingleton<LLIMModel>
 	/**
 	 * Add message to a list of message associated with session specified by session_id
 	 */
-	bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const LLSD& bonus = LLSD());
+	bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false, const LLSD& bonus = LLSD());
 
 };
 
@@ -352,8 +352,8 @@ class LLIMMgr final : public LLSingleton<LLIMMgr>
 					U32 parent_estate_id = 0,
 					const LLUUID& region_id = LLUUID::null,
 					const LLVector3& position = LLVector3::zero,
-					bool link_name = false,
-                    const LLSD& bonus = LLSD());
+					bool is_region_msg = false,
+					const LLSD& bonus = LLSD());
 
 	void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index de9ee65cfd1b877bd01dbbb229bdd296252df4ba..409fb330a054d88e8154d1f5a5267c9ec03e9fe2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -671,7 +671,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
 		if (cat)
 		{
 			LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id);
-			if (!cat_br.isItemCopyable())
+			if (!cat_br.isItemCopyable(false))
 			return FALSE;
 			// Skip to the next item in the clipboard
 			continue;
@@ -679,7 +679,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
 
 		// Each item must be copyable to be pastable
 		LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
-		if (!item_br.isItemCopyable())
+		if (!item_br.isItemCopyable(false))
 		{
 			return FALSE;
 		}
@@ -711,6 +711,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
 			{
 				return FALSE;
 			}
+
+            if (gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID()))
+            {
+                return FALSE;
+            }
 		}
 		const LLViewerInventoryCategory *cat = model->getCategory(objects.at(i));
 		if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
@@ -786,15 +791,15 @@ void hide_context_entries(LLMenuGL& menu,
 		}
 
 		bool found = false;
-		menuentry_vec_t::const_iterator itor2;
-		for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2)
-		{
-			if (*itor2 == name)
-			{
-				found = true;
-				break;
-			}
-		}
+
+        std::string myinput;
+        std::vector<std::string> mylist{ "a", "b", "c" };
+
+        menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name);
+        if (itor2 != entries_to_show.end())
+        {
+            found = true;
+        }
 
 		// Don't allow multiple separators in a row (e.g. such as if there are no items
 		// between two separators).
@@ -812,7 +817,21 @@ void hide_context_entries(LLMenuGL& menu,
 				menu_item->setVisible(FALSE);
 			}
 
-			menu_item->setEnabled(FALSE);
+            if (menu_item->getEnabled())
+            {
+                // These should stay enabled unless specifically disabled
+                const menuentry_vec_t exceptions = {
+                    "Detach From Yourself",
+                    "Wearable And Object Wear",
+                    "Wearable Add",
+                };
+
+                menuentry_vec_t::const_iterator itor2 = std::find(exceptions.begin(), exceptions.end(), name);
+                if (itor2 == exceptions.end())
+                {
+                    menu_item->setEnabled(FALSE);
+                }
+            }
 		}
 		else
 		{
@@ -970,7 +989,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 		disabled_items.push_back(std::string("Paste"));
 	}
 
-	if (gSavedSettings.getBOOL("InventoryLinking"))
+    static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
+	if (inventory_linking)
 	{
 		items.push_back(std::string("Paste As Link"));
 		if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0)
@@ -2205,7 +2225,8 @@ BOOL LLItemBridge::removeItem()
 // [SL:KB] - Patch: Inventory-Links | Checked: 2010-06-01 (Catznip-2.0)
 	// Users move folders around and reuse links that way... if we know something has links then it's just bad not to warn them :|
 // [/SL:KB]
-//	if (!gSavedSettings.getBOOL("InventoryLinking"))
+//    static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
+//	if (!inventory_linking)
 	{
 		if (!item->getIsLinkType())
 		{
@@ -2248,34 +2269,38 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo
 	return FALSE;
 }
 
-BOOL LLItemBridge::isItemCopyable() const
+bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const
 {
-	LLViewerInventoryItem* item = getItem();
-	if (item)
-	{
-//		// Can't copy worn objects.
-//		// Worn objects are tied to their inworld conterparts
-//		// Copy of modified worn object will return object with obsolete asset and inventory
-//		if(get_is_item_worn(mUUID))
-//			return FALSE;
-//		}
+    LLViewerInventoryItem* item = getItem();
+    if (!item)
+    {
+        return false;
+    }
+//    // Can't copy worn objects.
+//    // Worn objects are tied to their inworld conterparts
+//    // Copy of modified worn object will return object with obsolete asset and inventory
+//    if (get_is_item_worn(mUUID))
+//    {
+//        return false;
+//    }
 
 // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0)
-		// We'll allow copying a link if:
-		//   - its target is available
-		//   - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case]
-		if (item->getIsLinkType())
-		{
-			return (NULL != item->getLinkedItem());
-		}
+	// We'll allow copying a link if:
+	//   - its target is available
+	//   - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case]
+	if (item->getIsLinkType())
+	{
+		return (NULL != item->getLinkedItem());
+	}
 // [/SL:KB]
 
 // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.0)
-		return (item->getPermissions().allowCopyBy(gAgent.getID()));
+    return (can_copy_as_link)
+        || item->getPermissions().allowCopyBy(gAgent.getID());
 // [/SL:KB]
-//		return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking");
-	}
-	return FALSE;
+//	static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
+//    return (can_copy_as_link && inventory_linking)
+//        || item->getPermissions().allowCopyBy(gAgent.getID());
 }
 
 BOOL LLItemBridge::isItemModifyable() const
@@ -2499,7 +2524,7 @@ BOOL LLFolderBridge::isUpToDate() const
 	return (category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) || (mUUID == gLocalInventory) || (gInventory.isObjectDescendentOf(mUUID, gLocalInventory));
 }
 
-BOOL LLFolderBridge::isItemCopyable() const
+bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const
 {
 	// Folders are copyable if items in them are, recursively, copyable.
 	
@@ -2514,22 +2539,26 @@ BOOL LLFolderBridge::isItemCopyable() const
 	{
 		LLInventoryItem* item = *iter;
 		LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID());
-		if (!item_br.isItemCopyable())
-			return FALSE;
-}
+        if (!item_br.isItemCopyable(false))
+        {
+            return false;
+        }
+    }
 
 	// Check the folders
 	LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
 	for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
-{
+    {
 		LLViewerInventoryCategory* category = *iter;
 		LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID());
-		if (!cat_br.isItemCopyable())
-			return FALSE;
-	}
-	
-		return TRUE;
-	}
+        if (!cat_br.isItemCopyable(false))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
 
 // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6)
 bool LLFolderBridge::isItemLinkable() const
@@ -3980,6 +4009,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
 			LLInventoryObject *obj = model->getObject(item_id);
 			if (obj)
 			{
+
 				if (move_is_into_lost_and_found)
 				{
 					if (LLAssetType::AT_CATEGORY == obj->getType())
@@ -4515,7 +4545,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 			items.push_back(std::string("IM All Contacts In Folder"));
 		}
 
-        if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
+        if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT))
         {
             items.push_back(std::string("Ungroup folder items"));
         }
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 21c12cfee388442e235b5324aac9376b3017c42c..807c0cfd4fd1ac8777cee20f81c7857793609731 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -119,7 +119,7 @@ class LLInvFVBridge : public LLFolderViewModelItemInventory
 	//virtual BOOL removeItem() = 0;
 	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
 	virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
-	virtual BOOL isItemCopyable() const { return FALSE; }
+    virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; }
 	virtual BOOL isItemModifyable() const { return FALSE; }
 // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6)
 	virtual bool isItemLinkable() const { return FALSE; }
@@ -249,7 +249,7 @@ class LLItemBridge : public LLInvFVBridge
 	virtual BOOL isItemRenameable() const;
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL removeItem();
-	virtual BOOL isItemCopyable() const;
+    virtual bool isItemCopyable(bool can_copy_as_link = true) const;
 	virtual BOOL isItemModifyable() const;
 // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6)
 	/*virtual*/ bool isItemLinkable() const;
@@ -326,7 +326,7 @@ class LLFolderBridge : public LLInvFVBridge
 	virtual BOOL isItemRemovable() const;
 	virtual BOOL isItemMovable() const ;
 	virtual BOOL isUpToDate() const;
-	virtual BOOL isItemCopyable() const;
+    virtual bool isItemCopyable(bool can_copy_as_link = true) const;
 // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6)
 	/*virtual*/ bool isItemLinkable() const;
 // [/SL:KB]
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ce1048f2c266993008d8a168bef7867b144acd25..9bbedb02246d6aec3cbb66fca97dff52ad33222a 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -927,6 +927,9 @@ LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId)
 S32 depth_nesting_in_marketplace(LLUUID cur_uuid)
 {
     // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none
+    // Todo: findCategoryUUIDForType is somewhat expensive with large
+    // flat root folders yet we use depth_nesting_in_marketplace at
+    // every turn, find a way to correctly cache this id.
     const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
     if (marketplace_listings_uuid.isNull())
     {
@@ -1566,7 +1569,12 @@ void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level)
 // This function does no deletion of listings but a mere audit and raises issues to the user (through the
 // optional callback cb). It also returns a boolean, true if things validate, false if issues are raised.
 // The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders.
-bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth)
+bool validate_marketplacelistings(
+    LLInventoryCategory* cat,
+    validation_callback_t cb,
+    bool fix_hierarchy,
+    S32 depth,
+    bool notify_observers)
 {
 #if 0
     // Used only for debug
@@ -1632,7 +1640,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
             LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName());
             LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid);
             gInventory.changeCategoryParent(viewer_cat, folder_uuid, false);
-            result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1);
+            result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1, notify_observers);
             return result;
         }
         else
@@ -1802,7 +1810,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
                     // Next type
                     update_marketplace_category(parent_uuid);
                     update_marketplace_category(folder_uuid);
-                    gInventory.notifyObservers();
+                    if (notify_observers)
+                    {
+                        gInventory.notifyObservers();
+                    }
                     items_vector_it++;
                 }
             }
@@ -1816,7 +1827,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
                 {
                     LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter);
                     gInventory.changeCategoryParent(viewer_cat, parent_uuid, false);
-                    result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth);
+                    result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth, false);
                 }
             }
         }
@@ -1888,7 +1899,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
                 cb(message,depth,LLError::LEVEL_WARN);
             }
             gInventory.removeCategory(cat->getUUID());
-            gInventory.notifyObservers();
+            if (notify_observers)
+            {
+                gInventory.notifyObservers();
+            }
             return result && !has_bad_items;
         }
     }
@@ -1902,11 +1916,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
 	for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
 	{
 		LLInventoryCategory* category = *iter;
-		result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1);
+		result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1, false);
 	}
     
     update_marketplace_category(cat->getUUID(), true, true);
-    gInventory.notifyObservers();
+    if (notify_observers)
+    {
+        gInventory.notifyObservers();
+    }
     return result && !has_bad_items;
 }
 
@@ -2645,8 +2662,62 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
 	}
 
 	std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
+
+    // copy list of applicable items into a vector for bulk handling
     uuid_vec_t ids;
-    std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+    if (action == "wear" || action == "wear_add")
+    {
+        const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+        const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+        std::copy_if(selected_uuid_set.begin(),
+            selected_uuid_set.end(),
+            std::back_inserter(ids),
+            [trash_id, mp_id](LLUUID id)
+        {
+            if (get_is_item_worn(id)
+                || LLAppearanceMgr::instance().getIsInCOF(id)
+                || gInventory.isObjectDescendentOf(id, trash_id))
+            {
+                return false;
+            }
+            if (mp_id.notNull() && gInventory.isObjectDescendentOf(id, mp_id))
+            {
+                return false;
+            }
+            LLInventoryObject* obj = (LLInventoryObject*)gInventory.getObject(id);
+            if (!obj)
+            {
+                return false;
+            }
+            if (obj->getIsLinkType() && gInventory.isObjectDescendentOf(obj->getLinkedUUID(), trash_id))
+            {
+                return false;
+            }
+            if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType()))
+            {
+                // missing
+                return false;
+            }
+            return true;
+        }
+        );
+    }
+    else if (isRemoveAction(action))
+    {
+        std::copy_if(selected_uuid_set.begin(),
+            selected_uuid_set.end(),
+            std::back_inserter(ids),
+            [](LLUUID id)
+        {
+            return get_is_item_worn(id);
+        }
+        );
+    }
+    else
+    {
+        std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+    }
+
     // Check for actions that get handled in bulk
     if (action == "wear")
     {
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 354276a16e967b941b206bad60be9ce76e91ffa1..23a63ea033572a3476325bb1d5c64e0d9a1e44a2 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -97,7 +97,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve
 bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1, bool check_items = true, bool from_paste = false);
 bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false);
 bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false, bool move_no_copy_items = false);
-bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1);
+bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1, bool notify_observers = true);
 S32  depth_nesting_in_marketplace(LLUUID cur_uuid);
 LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
 S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 4976cd5b39768ed2c4a2317b972591bb49f70280..509c43acb07181400ba4219f8e17bec08b35fb5f 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -2004,9 +2004,13 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
             mChangedItemIDs.insert(referent);
         }
 
-        // Fix me: From DD-81, probably shouldn't be here, instead
-        // should be somewhere in an observer
-        update_marketplace_category(referent, false);
+        if (mask != LLInventoryObserver::LABEL)
+        {
+            // Fix me: From DD-81, probably shouldn't be here, instead
+            // should be somewhere in an observer or in
+            // LLMarketplaceInventoryObserver::onIdleProcessQueue
+            update_marketplace_category(referent, false);
+        }
 
         if (mask & LLInventoryObserver::ADD)
         {
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 6899618d7f3d58223cfbfd830c573381bf5c0ea2..569982172777e1669df6760cdbdc0b134801e57e 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -30,6 +30,7 @@
 
 #include "llagent.h"
 #include "llbufferstream.h"
+#include "llcallbacklist.h"
 #include "llinventoryfunctions.h"
 #include "llinventoryobserver.h"
 #include "llnotificationsutil.h"
@@ -603,20 +604,67 @@ class LLMarketplaceInventoryObserver : public LLInventoryObserver
 	LLMarketplaceInventoryObserver() {}
 	virtual ~LLMarketplaceInventoryObserver() {}
 	virtual void changed(U32 mask);
+
+private:
+    static void onIdleProcessQueue(void *userdata);
+
+    // doesn't hold just marketplace related ids
+    static std::set<LLUUID> sAddQueue;
+    static std::set<LLUUID> sStructureQueue;
+    static bool sProcessingQueue;
 };
 
+std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue;
+std::set<LLUUID> LLMarketplaceInventoryObserver::sStructureQueue;
+bool LLMarketplaceInventoryObserver::sProcessingQueue = false;
+
 void LLMarketplaceInventoryObserver::changed(U32 mask)
 {
-    // When things are added to the marketplace, we might need to re-validate and fix the containing listings
-	if (mask & LLInventoryObserver::ADD)
+	if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting())
 	{
+        // When things are added to the marketplace, we might need to re-validate and fix the containing listings
+        // just add whole list even if it contains items and non-marketplace folders
         const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
-        
-        std::set<LLUUID>::const_iterator id_it = changed_items.begin();
-        std::set<LLUUID>::const_iterator id_end = changed_items.end();
+        sAddQueue.insert(changed_items.begin(), changed_items.end());
+	}
+    
+	if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
+	{
+        // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
+        // * stock counts changing : no copy items coming in and out will change the stock count on folders
+        // * version and listing folders : moving those might invalidate the marketplace data itself
+        // Since we should cannot raise inventory change while the observer is called (the list will be cleared
+        // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.
+        const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
+        sStructureQueue.insert(changed_items.begin(), changed_items.end());
+	}
+
+    if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty()))
+    {
+        gIdleCallbacks.addFunction(onIdleProcessQueue, NULL);
+        // can do without sProcessingQueue, but it's usufull for simplicity and reliability
+        sProcessingQueue = true;
+    }
+}
+
+void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)
+{
+    U64 start_time = LLTimer::getTotalTime(); // microseconds
+    const U64 MAX_PROCESSING_TIME = 1000;
+    U64 stop_time = start_time + MAX_PROCESSING_TIME;
+
+    if (!sAddQueue.empty())
+    {
+        // Make a copy of sAddQueue since decrementValidationWaiting
+        // can theoretically add more items
+        std::set<LLUUID> add_queue(sAddQueue);
+        sAddQueue.clear();
+
+        std::set<LLUUID>::const_iterator id_it = add_queue.begin();
+        std::set<LLUUID>::const_iterator id_end = add_queue.end();
         // First, count the number of items in this list...
         S32 count = 0;
-        for (;id_it != id_end; ++id_it)
+        for (; id_it != id_end; ++id_it)
         {
             LLInventoryObject* obj = gInventory.getObject(*id_it);
             if (obj && (LLAssetType::AT_CATEGORY != obj->getType()))
@@ -627,56 +675,58 @@ void LLMarketplaceInventoryObserver::changed(U32 mask)
         // Then, decrement the folders of that amount
         // Note that of all of those, only one folder will be a listing folder (if at all).
         // The other will be ignored by the decrement method.
-        id_it = changed_items.begin();
-        for (;id_it != id_end; ++id_it)
+        id_it = add_queue.begin();
+        for (; id_it != id_end; ++id_it)
         {
             LLInventoryObject* obj = gInventory.getObject(*id_it);
             if (obj && (LLAssetType::AT_CATEGORY == obj->getType()))
             {
-                LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(),count);
+                // can trigger notifyObservers
+                LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count);
             }
         }
-	}
-    
-    // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder:
-    // * stock counts changing : no copy items coming in and out will change the stock count on folders
-    // * version and listing folders : moving those might invalidate the marketplace data itself
-    // Since we should cannot raise inventory change while the observer is called (the list will be cleared
-    // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.
-    
-	if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE))
-	{
-        const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();
-    
-        std::set<LLUUID>::const_iterator id_it = changed_items.begin();
-        std::set<LLUUID>::const_iterator id_end = changed_items.end();
-        for (;id_it != id_end; ++id_it)
+    }
+
+    while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time)
+    {
+        std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin();
+        LLInventoryObject* obj = gInventory.getObject(*id_it);
+        if (obj)
         {
-            LLInventoryObject* obj = gInventory.getObject(*id_it);
-            if (obj)
+            if (LLAssetType::AT_CATEGORY == obj->getType())
             {
-                if (LLAssetType::AT_CATEGORY == obj->getType())
+                // If it's a folder known to the marketplace, let's check it's in proper shape
+                if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it))
                 {
-                    // If it's a folder known to the marketplace, let's check it's in proper shape
-                    if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it))
-                    {
-                        LLInventoryCategory* cat = (LLInventoryCategory*)(obj);
-                        validate_marketplacelistings(cat);
-                    }
+                    LLInventoryCategory* cat = (LLInventoryCategory*)(obj);
+                    // can trigger notifyObservers
+                    // can cause more structural changes
+                    validate_marketplacelistings(cat);
                 }
-                else
+            }
+            else
+            {
+                // If it's not a category, it's an item...
+                LLInventoryItem* item = (LLInventoryItem*)(obj);
+                // If it's a no copy item, we may need to update the label count of marketplace listings
+                if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
                 {
-                    // If it's not a category, it's an item...
-                    LLInventoryItem* item = (LLInventoryItem*)(obj);
-                    // If it's a no copy item, we may need to update the label count of marketplace listings
-                    if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
-                    {
-                        LLMarketplaceData::instance().setDirtyCount();
-                    }
+                    LLMarketplaceData::instance().setDirtyCount();
                 }
             }
         }
-	}
+
+        // sStructureQueue could have been modified in validate_marketplacelistings
+        // adding items does not invalidate existing iterator
+        sStructureQueue.erase(id_it);
+    }
+
+    if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty()))
+    {
+        // Nothing to do anymore
+        gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL);
+        sProcessingQueue = false;
+    }
 }
 
 // Tuple == Item
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 4d41e6c1e666e559cba04f095eb10c6c5295a4e3..ba9864001cfc47f160f894cdae154941c1872c24 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -242,6 +242,7 @@ class LLMarketplaceData final
     void setUpdating(const LLUUID& folder_id, bool isUpdating);
     
     // Used to decide when to run a validation on listing folders
+    bool hasValidationWaiting() { return mValidationWaitingList.size() > 0; }
     void setValidationWaiting(const LLUUID& folder_id, S32 count);
     void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1);
 
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 10f0dbb4e98177ffad98c05c3b88d2961529dfba..6de87e951bf0559f0d91a2d02f7718c23b8155c3 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -38,7 +38,7 @@
 #include "llfilepicker.h"
 #include "llfloaterperms.h"
 #include "llfloaterreg.h"
-#include "llfloateroutfitsnapshot.h"
+#include "llfloatersimpleoutfitsnapshot.h"
 #include "llimagedimensionsinfo.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
@@ -1402,8 +1402,8 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
 
 void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id)
 {
-    LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot");
-    LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance();
+    LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot");
+    LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance();
     if (snapshot_floater)
     {
         snapshot_floater->setOutfitID(selected_outfit_id);
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index e1818cc68b3933c3d775e694690c958f6e6e823f..416857bd305f2b22567a03381c30065d14c2a65f 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -454,7 +454,8 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
 							LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
 						if(media_impl)
 						{
-							media_impl->navigateHome();
+                            media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL);
+                            media_impl->navigateHome();
 							return true;
 						}
 					}
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index d9310d202d9c784f2fb7a8af5812ddabbeaf293b..cabf189cad3413737bdabf27ef8fbdb5f123619f 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -112,6 +112,8 @@ enum {
 	MI_HOLE_COUNT
 };
 
+const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
+
 //static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright");
 
 BOOL	LLPanelObject::postBuild()
@@ -1889,6 +1891,16 @@ void LLPanelObject::sendPosition(BOOL btn_down)
 		// won't get dumped by the simulator.
 		new_pos_global = regionp->getPosGlobalFromRegion(newpos);
 	}
+    else
+    {
+        if (newpos.length() > MAX_ATTACHMENT_DIST)
+        {
+            newpos.clampLength(MAX_ATTACHMENT_DIST);
+            mCtrlPosX->set(newpos.mV[VX]);
+            mCtrlPosY->set(newpos.mV[VY]);
+            mCtrlPosZ->set(newpos.mV[VZ]);
+        }
+    }
 
 	if (mObject->isAttachment())
 	{	
@@ -2435,6 +2447,10 @@ void LLPanelObject::onPastePos()
         mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width);
         //height will get properly clamped by sendPosition
     }
+    else
+    {
+        mClipboardPos.clampLength(MAX_ATTACHMENT_DIST);
+    }
 
     mCtrlPosX->set( mClipboardPos.mV[VX] );
     mCtrlPosY->set( mClipboardPos.mV[VY] );
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index b015aecf8493cd1590d41ce20952f93d00a9ad00..657d79d8d724c92205a1f7981e51c38292e48f49 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -136,7 +136,7 @@ class LLTaskInvFVBridge : public LLFolderViewModelItemInventory
 	virtual BOOL removeItem();
 	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
 	virtual void move(LLFolderViewModelItem* parent_listener);	
-	virtual BOOL isItemCopyable() const;
+    virtual bool isItemCopyable(bool can_copy_as_link = true) const;
 // [SL:KB] - Patch: Inventory-Actions | Checked: 2013-09-19 (Catznip-3.6)
 	/*virtual*/ bool isItemLinkable() const;
 	/*virtual*/ BOOL isLink() const;
@@ -497,10 +497,10 @@ void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
 {
 }
 
-BOOL LLTaskInvFVBridge::isItemCopyable() const
+bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const
 {
 	LLInventoryItem* item = findItem();
-	if(!item) return FALSE;
+	if(!item) return false;
 	return gAgent.allowOperation(PERM_COPY, item->getPermissions(),
 								GP_OBJECT_MANIPULATE);
 }
diff --git a/indra/newview/llpanelpresetscamerapulldown.cpp b/indra/newview/llpanelpresetscamerapulldown.cpp
index 0accf12cbe172f945bf88a214af6f8241d525966..e1fd248d18ed30fe99aa98e5678a64c96bf7f51e 100644
--- a/indra/newview/llpanelpresetscamerapulldown.cpp
+++ b/indra/newview/llpanelpresetscamerapulldown.cpp
@@ -125,7 +125,10 @@ void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data)
             LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
 			LLFloaterCamera::switchToPreset(name);
 
-			setVisible(FALSE);
+            // Scroll grabbed focus, drop it to prevent selection of parent menu
+            setFocus(FALSE);
+
+            setVisible(FALSE);
 		}
         else
         {
diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp
index d52ad8056fc75849b1d717dfe4572a32f9891b13..23e4fa8887dfde2bf53e868b322d76c5b78d452c 100644
--- a/indra/newview/llpanelpresetspulldown.cpp
+++ b/indra/newview/llpanelpresetspulldown.cpp
@@ -122,6 +122,9 @@ void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data)
             LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL;
 			LLPresetsManager::getInstance()->loadPreset(PRESETS_GRAPHIC, name);
 
+            // Scroll grabbed focus, drop it to prevent selection of parent menu
+            setFocus(FALSE);
+
 			setVisible(FALSE);
 		}
         else
diff --git a/indra/newview/llpanelpulldown.cpp b/indra/newview/llpanelpulldown.cpp
index 4de6ee81829eadd0910a13d049d02035a70bbbba..075278f44ccbb987ebc080fead3525ca36bd6b19 100644
--- a/indra/newview/llpanelpulldown.cpp
+++ b/indra/newview/llpanelpulldown.cpp
@@ -51,6 +51,7 @@ void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask)
 /*virtual*/
 void LLPanelPulldown::onTopLost()
 {
+    setFocus(FALSE); // drop focus to prevent transfer to parent
     setVisible(FALSE);
 }
 
@@ -113,6 +114,7 @@ void LLPanelPulldown::draw()
 
     if (alpha == 0.f)
     {
+        setFocus(FALSE); // drop focus to prevent transfer to parent
         setVisible(FALSE);
     }
 }
diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp
index c6bb2f19dd45a47b90394ae550ec79b0bcb3f3f7..140cbbedbecd027f4b7a0e38ecef50dacd363d7c 100644
--- a/indra/newview/llscripteditor.cpp
+++ b/indra/newview/llscripteditor.cpp
@@ -187,82 +187,8 @@ void LLScriptEditor::drawSelectionBackground()
 	// Draw selection even if we don't have keyboard focus for search/replace
 	if( hasSelection() && !mLineInfoList.empty())
 	{
-		std::vector<LLRect> selection_rects;
-		
-		S32 selection_left		= llmin( mSelectionStart, mSelectionEnd );
-		S32 selection_right		= llmax( mSelectionStart, mSelectionEnd );
-		
-		// Skip through the lines we aren't drawing.
-		LLRect content_display_rect = getVisibleDocumentRect();
-		
-		// binary search for line that starts before top of visible buffer
-		line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, LLTextBase::compare_bottom());
-		line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top());
-		
-		bool done = false;
-		
-		// Find the coordinates of the selected area
-		for (;line_iter != end_iter && !done; ++line_iter)
-		{
-			// is selection visible on this line?
-			if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
-			{
-				segment_set_t::iterator segment_iter;
-				S32 segment_offset;
-				getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
-				
-				LLRect selection_rect;
-				selection_rect.mLeft = line_iter->mRect.mLeft;
-				selection_rect.mRight = line_iter->mRect.mLeft;
-				selection_rect.mBottom = line_iter->mRect.mBottom;
-				selection_rect.mTop = line_iter->mRect.mTop;
-				
-				for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
-				{
-					LLTextSegmentPtr segmentp = *segment_iter;
-					
-					S32 segment_line_start = segmentp->getStart() + segment_offset;
-					S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
-					
-					if (segment_line_start > segment_line_end) break;
-					
-					S32 segment_width = 0;
-					S32 segment_height = 0;
-					
-					// if selection after beginning of segment
-					if(selection_left >= segment_line_start)
-					{
-						S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
-						segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
-						selection_rect.mLeft += segment_width;
-					}
-					
-					// if selection_right == segment_line_end then that means we are the first character of the next segment
-					// or first character of the next line, in either case we want to add the length of the current segment
-					// to the selection rectangle and continue.
-					// if selection right > segment_line_end then selection spans end of current segment...
-					if (selection_right >= segment_line_end)
-					{
-						// extend selection slightly beyond end of line
-						// to indicate selection of newline character (use "n" character to determine width)
-						S32 num_chars = segment_line_end - segment_line_start;
-						segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
-						selection_rect.mRight += segment_width;
-					}
-					// else if selection ends on current segment...
-					else
-					{
-						S32 num_chars = selection_right - segment_line_start;
-						segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
-						selection_rect.mRight += segment_width;
-						
-						break;
-					}
-				}
-				selection_rects.push_back(selection_rect);
-			}
-		}
-		
+        std::vector<LLRect> selection_rects = getSelctionRects();
+
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor;
 		F32 alpha = hasFocus() ? 0.7f : 0.3f;
@@ -272,6 +198,7 @@ void LLScriptEditor::drawSelectionBackground()
 								 (1.f + color.mV[VGREEN]) * 0.5f,
 								 (1.f + color.mV[VBLUE]) * 0.5f,
 								 alpha);
+        LLRect content_display_rect = getVisibleDocumentRect();
 		
 		for (std::vector<LLRect>::iterator rect_it = selection_rects.begin();
 			 rect_it != selection_rects.end();
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index 8c0d70c16c93d3b310febd87a3b4fb75748e8c8b..ec0de1fbfde636f59ea1996c65853def4adf6cc2 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -39,7 +39,6 @@
 class LLViewerCamera;
 
 class LLVOWLSky;
-class LLVOWLClouds;
 
 
 class LLSky  
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 0d64d642a56f014203fadc6f67c424fa121d4db7..259d49755fd2908ba71a8c2f444b8e588b242bbf 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -234,7 +234,7 @@ bool LLSnapshotLivePreview::setSnapshotQuality(S32 quality, bool set_by_user)
     return false;
 }
 
-void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
+void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color)
 {
 	F32 line_width ; 
 	glGetFloatv(GL_LINE_WIDTH, &line_width) ;
@@ -247,7 +247,6 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
 	//draw four alpha rectangles to cover areas outside of the snapshot image
 	if(!mKeepAspectRatio)
 	{
-		LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ;
 		S32 dwl = 0, dwr = 0 ;
 		if(mThumbnailWidth > mPreviewRect.getWidth())
 		{
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
index 683cd016d8387d05ddd6652fc8f224bce1357f9b..1f81307976797f0ac52a2b3641b0515a0d35cbb0 100644
--- a/indra/newview/llsnapshotlivepreview.h
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -112,7 +112,7 @@ class LLSnapshotLivePreview : public LLView
 	BOOL setThumbnailImageSize() ;
 	void generateThumbnailImage(BOOL force_update = FALSE) ;
 	void resetThumbnailImage() { mThumbnailImage = NULL ; }
-	void drawPreviewRect(S32 offset_x, S32 offset_y) ;
+	void drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color = LLColor4(0.5f, 0.5f, 0.5f, 0.8f));
 	void prepareFreezeFrame();
     
 	LLViewerTexture* getBigThumbnailImage();
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6e4106eb036c09cbc444f13e78aa4d2b90373d0b..2fa728c9f09d0a06a4e8e5df31aa2470a3ba00c5 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1354,9 +1354,6 @@ bool idle_startup()
 		// Initialize classes w/graphics stuff.
 		//
 		LLViewerStatsRecorder::instance(); // Since textures work in threads
-		gTextureList.doPrefetchImages();		
-		display_startup();
-
 		LLSurface::initClasses();
 		display_startup();
 
@@ -1499,6 +1496,15 @@ bool idle_startup()
 	if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState())
 	{
 		display_startup();
+
+        // These textures are not warrantied to be cached, so needs
+        // to hapen with caps granted
+        gTextureList.doPrefetchImages();
+
+        // will init images, should be done with caps, but before gSky.init()
+        LLEnvironment::getInstance()->initSingleton();
+
+        display_startup();
 		update_texture_fetch();
 		display_startup();
 
@@ -2613,8 +2619,6 @@ void use_circuit_callback(void**, S32 result)
 void register_viewer_callbacks(LLMessageSystem* msg)
 {
 	msg->setHandlerFuncFast(_PREHASH_LayerData,				process_layer_data );
-	msg->setHandlerFuncFast(_PREHASH_ImageData,				LLViewerTextureList::receiveImageHeader );
-	msg->setHandlerFuncFast(_PREHASH_ImagePacket,				LLViewerTextureList::receiveImagePacket );
 	msg->setHandlerFuncFast(_PREHASH_ObjectUpdate,				process_object_update );
 	msg->setHandlerFuncFast(_PREHASH_ObjectUpdateCompressed,				process_compressed_object_update );
 	msg->setHandlerFuncFast(_PREHASH_ObjectUpdateCached,					process_cached_object_update );
@@ -3016,6 +3020,7 @@ void reset_login()
 	gAgentWearables.cleanup();
 	gAgentCamera.cleanup();
 	gAgent.cleanup();
+    gSky.cleanup(); // mVOSkyp is an inworld object.
 	LLWorld::getInstance()->resetClass();
 
 	if ( gViewerWindow )
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 81a41b08fc1061ac6e0f7d1584f2e799912e8565..a1c9781966f12c8f9f079a0afb117a64f4443070 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -747,7 +747,7 @@ BOOL LLSurfacePatch::updateTexture()
 				{
 					mVObjp->dirtyGeom();
 					gPipeline.markGLRebuild(mVObjp);
-					return TRUE;
+					return !mSTexUpdate;
 				}
 			}
 		}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 567d1f0bc85ecd05ca8096d88f4b5190470b9191..2aabb6a5c3c7c4fcc160edf6d439d98c79f9e443 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1653,6 +1653,12 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
 			{
 				gDirUtilp->deleteFilesInDir(dirname, mask);
 			}
+#if LL_WINDOWS
+            // Texture cache can be large and can take a while to remove
+            // assure OS that processes is alive and not hanging
+            MSG msg;
+            PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD);
+#endif
 		}
 		gDirUtilp->deleteFilesInDir(mTexturesDirName, mask); // headers, fast cache
 		if (purge_directories)
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 128568ea4b4049b18b95281695955775f570d769..34bbf381d7ab2d1fc79ca0d71c1adf6144d35dfc 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -282,7 +282,6 @@ static const char* e_state_name[] =
 	"LOAD_FROM_TEXTURE_CACHE",
 	"CACHE_POST",
 	"LOAD_FROM_NETWORK",
-	"LOAD_FROM_SIMULATOR",
 	"WAIT_HTTP_RESOURCE",
 	"WAIT_HTTP_RESOURCE2",
 	"SEND_HTTP_REQ",
@@ -456,7 +455,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 		LOAD_FROM_TEXTURE_CACHE,
 		CACHE_POST,
 		LOAD_FROM_NETWORK,
-		LOAD_FROM_SIMULATOR,
 		WAIT_HTTP_RESOURCE,				// Waiting for HTTP resources
 		WAIT_HTTP_RESOURCE2,			// Waiting for HTTP resources
 		SEND_HTTP_REQ,					// Commit to sending as HTTP
@@ -497,8 +495,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	// Locks:  Mw
 	void clearPackets();
 
-	// Locks:  Mw
-	void setupPacketData();
 
 	// Locks:  Mw (ctor invokes without lock)
 	U32 calcWorkPriority();
@@ -506,10 +502,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	// Locks:  Mw
 	void removeFromCache();
 
-	// Threads:  Ttf
-	// Locks:  Mw
-	bool processSimulatorPackets();
-
 	// Threads:  Ttf
 	bool writeToCacheComplete();
 	
@@ -612,8 +604,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	BOOL mHaveAllData;
 	BOOL mInLocalCache;
 	BOOL mInCache;
-	bool                        mCanUseHTTP,
-								mCanUseNET ; //can get from asset server.
+    bool                        mCanUseHTTP;
 	S32 mRetryAttempt;
 	S32 mActiveCount;
 	LLCore::HttpStatus mGetStatus;
@@ -885,7 +876,6 @@ const char* sStateDescs[] = {
 	"LOAD_FROM_TEXTURE_CACHE",
 	"CACHE_POST",
 	"LOAD_FROM_NETWORK",
-	"LOAD_FROM_SIMULATOR",
 	"WAIT_HTTP_RESOURCE",
 	"WAIT_HTTP_RESOURCE2",
 	"SEND_HTTP_REQ",
@@ -897,7 +887,7 @@ const char* sStateDescs[] = {
 	"DONE"
 };
 
-const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, 
+const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK,
 										LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE };
 
 // static
@@ -972,8 +962,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mResourceWaitCount(0U),
 	  mFetchRetryPolicy(10.0,3600.0,2.0,10)
 {
-	mCanUseNET = mUrl.empty() ;
-	
 	calcWorkPriority();
 	mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
 // 	LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
@@ -1037,39 +1025,6 @@ void LLTextureFetchWorker::clearPackets()
 	mFirstPacket = 0;
 }
 
-// Locks:  Mw
-void LLTextureFetchWorker::setupPacketData()
-{
-	S32 data_size = 0;
-	if (mFormattedImage.notNull())
-	{
-		data_size = mFormattedImage->getDataSize();
-	}
-	if (data_size > 0)
-	{
-		// Only used for simulator requests
-		mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1;
-		if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size)
-		{
-			LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL;
-			removeFromCache();
-			resetFormattedData();
-			clearPackets();
-		}
-		else if (mFileSize > 0)
-		{
-			mLastPacket = mFirstPacket-1;
-			mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1;
-		}
-		else
-		{
-			// This file was cached using HTTP so we have to refetch the first packet
-			resetFormattedData();
-			clearPackets();
-		}
-	}
-}
-
 // Locks:  Mw (ctor invokes without lock)
 U32 LLTextureFetchWorker::calcWorkPriority()
 {
@@ -1177,7 +1132,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 	if(mImagePriority < F_ALMOST_ZERO)
 	{
-		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
+		if (mState == INIT || mState == LOAD_FROM_NETWORK)
 		{
 #ifdef SHOW_DEBUG
 			LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
@@ -1185,7 +1140,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			return true; // abort
 		}
 	}
-	if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
+	if(mState > CACHE_POST && !mCanUseHTTP)
 	{
 		//nowhere to get data, abort.
 		LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;
@@ -1396,10 +1351,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
 		{
 			LLViewerRegion* region = NULL;
-			if (mHost.isInvalid())
-				region = gAgent.getRegion();
-			else
-				region = LLWorld::getInstance()->getRegion(mHost);
+            if (mHost.isInvalid())
+            {
+                region = gAgent.getRegion();
+            }
+            else if (LLWorld::instanceExists())
+            {
+                region = LLWorld::getInstance()->getRegion(mHost);
+            }
 
 			if (region)
 			{
@@ -1424,18 +1383,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				else
 				{
 					mCanUseHTTP = false ;
-#ifdef SHOW_DEBUG
-					LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
-#endif
+					LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
 				}
 			}
 			else
 			{
 				// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
 				//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
-#ifdef SHOW_DEBUG
-				LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
-#endif
+                LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
 				mCanUseHTTP = false;
 			}
 		}
@@ -1454,86 +1409,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			// don't return, fall through to next state
 		}
-		else if (mSentRequest == UNSENT && mCanUseNET)
-		{
-			// Add this to the network queue and sit here.
-			// LLTextureFetch::update() will send off a request which will change our state
-			mWriteToCacheState = CAN_WRITE ;
-			mRequestedSize = mDesiredSize;
-			mRequestedDiscard = mDesiredDiscard;
-			mSentRequest = QUEUED;
-			mFetcher->addToNetworkQueue(this);
-			recordTextureStart(false);
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-			
-			return false;
-		}
 		else
 		{
-			// Shouldn't need to do anything here
-			//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
-			// Make certain this is in the network queue
-			//mFetcher->addToNetworkQueue(this);
-			//recordTextureStart(false);
-			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-
 			return false;
 		}
 	}
 	
-	if (mState == LOAD_FROM_SIMULATOR)
-	{
-		if (mFormattedImage.isNull())
-		{
-			mFormattedImage = new LLImageJ2C;
-		}
-		if (processSimulatorPackets())
-		{
-            // Capture some measure of total size for metrics
-            F64 byte_count = 0;
-            if (mLastPacket >= mFirstPacket)
-            {
-                for (S32 i=mFirstPacket; i<=mLastPacket; i++)
-                {
-                    llassert_always((i>=0) && (i<mPackets.size()));
-                    if (mPackets[i])
-                    {
-                        byte_count += mPackets[i]->mSize;
-                    }
-                }
-            }
-
-#ifdef SHOW_DEBUG
-			LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;
-#endif
-			mFetcher->removeFromNetworkQueue(this, false);
-			if (mFormattedImage.isNull() || !mFormattedImage->getDataSize())
-			{
-				// processSimulatorPackets() failed
-// 				LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL;
-				LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;
-				return true; // failed
-			}
-			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-			if (mLoadedDiscard < 0)
-			{
-				LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
-								  << ", should be >=0" << LL_ENDL;
-			}
-			setState(DECODE_IMAGE);
-			mWriteToCacheState = SHOULD_WRITE;
-
-			recordTextureDone(false, byte_count);
-		}
-		else
-		{
-			mFetcher->addToNetworkQueue(this); // failsafe
-			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-			recordTextureStart(false);
-		}
-		return false;
-	}
-	
 	if (mState == WAIT_HTTP_RESOURCE)
 	{
 		// NOTE:
@@ -1575,8 +1456,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL;
 			return true; // abort
 		}
-
-		mFetcher->removeFromNetworkQueue(this, false);
 			
 		S32 cur_size = 0;
 		if (mFormattedImage.notNull())
@@ -1725,17 +1604,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
 						}
 						return true; 
 					}
-
-					// roll back to try UDP
-					if (mCanUseNET)
-					{
-						setState(INIT);
-						mCanUseHTTP = false;
-						mUrl.clear();
-						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-						releaseHttpSemaphore();
-						return false;
-					}
 				}
 				else if (http_service_unavail == mGetStatus)
 				{
@@ -2326,69 +2194,6 @@ void LLTextureFetchWorker::removeFromCache()
 }
 
 
-//////////////////////////////////////////////////////////////////////////////
-
-// Threads:  Ttf
-// Locks:  Mw
-bool LLTextureFetchWorker::processSimulatorPackets()
-{
-	if (mFormattedImage.isNull() || mRequestedSize < 0)
-	{
-		// not sure how we got here, but not a valid state, abort!
-		llassert_always(mDecodeHandle == 0);
-		mFormattedImage = NULL;
-		return true;
-	}
-	
-	if (mLastPacket >= mFirstPacket)
-	{
-		S32 buffer_size = mFormattedImage->getDataSize();
-		for (S32 i = mFirstPacket; i<=mLastPacket; i++)
-		{
-            llassert_always((i>=0) && (i<mPackets.size()));
-			llassert_always(mPackets[i]);
-			buffer_size += mPackets[i]->mSize;
-		}
-		bool have_all_data = mLastPacket >= mTotalPackets-1;
-		if (mRequestedSize <= 0)
-		{
-			// We received a packed but haven't requested anything yet (edge case)
-			// Return true (we're "done") since we didn't request anything
-			return true;
-		}
-		if (buffer_size >= mRequestedSize || have_all_data)
-		{
-			/// We have enough (or all) data
-			if (have_all_data)
-			{
-				mHaveAllData = TRUE;
-			}
-			S32 cur_size = mFormattedImage->getDataSize();
-			if (buffer_size > cur_size)
-			{
-				/// We have new data
-				U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size);
-				S32 offset = 0;
-				if (cur_size > 0 && mFirstPacket > 0)
-				{
-					memcpy(buffer, mFormattedImage->getData(), cur_size);
-					offset = cur_size;
-				}
-				for (S32 i=mFirstPacket; i<=mLastPacket; i++)
-				{
-					memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize);
-					offset += mPackets[i]->mSize;
-				}
-				// NOTE: setData releases current data
-				mFormattedImage->setData(buffer, buffer_size);
-			}
-			mLoadedDiscard = mRequestedDiscard;
-			return true;
-		}
-	}
-	return false;
-}
-
 //////////////////////////////////////////////////////////////////////////////
 
 // Threads:  Ttf
@@ -2877,40 +2682,6 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
 }
 
 
-// Threads:  T* (but Ttf in practice)
-
-// protected
-void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
-{
-	lockQueue();														// +Mfq
-	bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
-	unlockQueue();														// -Mfq
-
-	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq		
-	if (in_request_map)
-	{
-		// only add to the queue if in the request map
-		// i.e. a delete has not been requested
-		mNetworkQueue.insert(worker->mID);
-	}
-	for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
-		 iter1 != mCancelQueue.end(); ++iter1)
-	{
-		iter1->second.erase(worker->mID);
-	}
-}																		// -Mfnq
-
-// Threads:  T*
-void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
-{
-	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq
-	size_t erased = mNetworkQueue.erase(worker->mID);
-	if (cancel && erased > 0)
-	{
-		mCancelQueue[worker->mHost].insert(worker->mID);
-	}
-}																		// -Mfnq
-
 // Threads:  T*
 //
 // protected
@@ -2944,7 +2715,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
 		unlockQueue();													// -Mfq
 
 		llassert_always(erased_1 > 0) ;
-		removeFromNetworkQueue(worker, cancel);
 		llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
 
 		worker->scheduleDelete();	
@@ -2972,7 +2742,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
 	unlockQueue();														// -Mfq
 
 	llassert_always(erased_1 > 0) ;
-	removeFromNetworkQueue(worker, cancel);
 	llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
 
 	worker->scheduleDelete();	
@@ -3217,17 +2986,6 @@ S32 LLTextureFetch::update(F32 max_time_ms)
 
 	S32 res = LLWorkerThread::update(max_time_ms);
 	
-	if (!mDebugPause)
-	{
-		// this is the startup state when send_complete_agent_movement() message is sent.
-		// Before this, the RequestImages message sent by sendRequestListToSimulators 
-		// won't work so don't bother trying
-		if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
-		{
-			sendRequestListToSimulators();			
-		}
-	}
-
 	if (!mThreaded)
 	{
 		commonUpdate();
@@ -3321,201 +3079,6 @@ void LLTextureFetch::threadedUpdate()
 
 //////////////////////////////////////////////////////////////////////////////
 
-// Threads:  Tmain
-void LLTextureFetch::sendRequestListToSimulators()
-{
-	// All requests
-	const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps
-	
-	// Sim requests
-	const S32 IMAGES_PER_REQUEST = 50;
-	const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp
-	const F32 MIN_REQUEST_TIME = 1.0f;
-	const F32 MIN_DELTA_PRIORITY = 1000.f;
-
-	// Periodically, gather the list of textures that need data from the network
-	// And send the requests out to the simulators
-	static LLFrameTimer timer;
-	if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME)
-	{
-		return;
-	}
-	timer.reset();
-	
-	// Send requests
-	typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t;
-	typedef std::map< LLHost, request_list_t > work_request_map_t;
-	work_request_map_t requests;
-	{
-		LLMutexLock lock2(&mNetworkQueueMutex);							// +Mfnq
-		for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
-		{
-			queue_t::iterator curiter = iter++;
-			LLTextureFetchWorker* req = getWorker(*curiter);
-			if (!req)
-			{
-				mNetworkQueue.erase(curiter);
-				continue; // paranoia
-			}
-			if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
-				(req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
-			{
-				// We already received our URL, remove from the queue
-				LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL;
-				mNetworkQueue.erase(curiter);
-				continue;
-			}
-			if (req->mID == mDebugID)
-			{
-				mDebugCount++; // for setting breakpoints
-			}
-			if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
-				req->mTotalPackets > 0 &&
-				req->mLastPacket >= req->mTotalPackets-1)
-			{
-				// We have all the packets... make sure this is high priority
-// 			req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
-				continue;
-			}
-			F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32();
-			{
-				F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
-				if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
-					(delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
-					(elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
-				{
-					requests[req->mHost].insert(req);
-				}
-			}
-		}
-	}																	// -Mfnq
-
-	for (auto& request : requests)
-    {
-		LLHost host = request.first;
-		// invalid host = use agent host
-		if (host.isInvalid())
-		{
-			host = gAgent.getRegionHost();
-		}
-
-		S32 sim_request_count = 0;
-		
-		for (LLTextureFetchWorker* req : request.second)
-        {
-			if (gMessageSystem)
-			{
-				if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM)
-				{
-					// Initialize packet data based on data read from cache
-					req->lockWorkMutex();								// +Mw
-					req->setupPacketData();
-					req->unlockWorkMutex();								// -Mw		
-				}
-				if (0 == sim_request_count)
-				{
-					gMessageSystem->newMessageFast(_PREHASH_RequestImage);
-					gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-					gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-					gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-				}
-				S32 packet = req->mLastPacket + 1;
-				gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
-				gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID);
-				gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard);
-				gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority);
-				gMessageSystem->addU32Fast(_PREHASH_Packet, packet);
-				gMessageSystem->addU8Fast(_PREHASH_Type, req->mType);
-// 				LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
-// 						<< " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL;
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-				static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
-				static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
-				if (log_to_viewer_log || log_to_sim)
-				{
-					mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
-					mTextureInfo.setRequestOffset(req->mID, 0);
-					mTextureInfo.setRequestSize(req->mID, 0);
-					mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP);
-				}
-#endif
-
-				req->lockWorkMutex();									// +Mw
-				req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
-				req->mSimRequestedDiscard = req->mDesiredDiscard;
-				req->mRequestedPriority = req->mImagePriority;
-				req->mRequestedDeltaTimer.reset();
-				req->unlockWorkMutex();									// -Mw
-				sim_request_count++;
-				if (sim_request_count >= IMAGES_PER_REQUEST)
-				{
-// 					LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
-
-					gMessageSystem->sendSemiReliable(host, NULL, NULL);
-					sim_request_count = 0;
-				}
-			}
-		}
-		if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST)
-		{
-// 			LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL;
-			gMessageSystem->sendSemiReliable(host, NULL, NULL);
-			sim_request_count = 0;
-		}
-	}
-	
-	// Send cancelations
-	{
-		LLMutexLock lock2(&mNetworkQueueMutex);							// +Mfnq
-		if (gMessageSystem && !mCancelQueue.empty())
-		{
-			for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
-				 iter1 != mCancelQueue.end(); ++iter1)
-			{
-				LLHost host = iter1->first;
-				if (host.isInvalid())
-				{
-					host = gAgent.getRegionHost();
-				}
-				S32 request_count = 0;
-				for (queue_t::iterator iter2 = iter1->second.begin();
-					 iter2 != iter1->second.end(); ++iter2)
-				{
-					if (0 == request_count)
-					{
-						gMessageSystem->newMessageFast(_PREHASH_RequestImage);
-						gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-						gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-						gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-					}
-					gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
-					gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
-					gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
-					gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
-					gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
-					gMessageSystem->addU8Fast(_PREHASH_Type, 0);
-// 				LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL;
-
-					request_count++;
-					if (request_count >= IMAGES_PER_REQUEST)
-					{
-						gMessageSystem->sendSemiReliable(host, NULL, NULL);
-						request_count = 0;
-					}
-				}
-				if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
-				{
-					gMessageSystem->sendSemiReliable(host, NULL, NULL);
-				}
-			}
-			mCancelQueue.clear();
-		}
-	}																	// -Mfnq
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
 // Threads:  T*
 // Locks:  Mw
 bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
@@ -3578,140 +3141,6 @@ void LLTextureFetchWorker::setState(e_state new_state)
 	mState = new_state;
 }
 
-// Threads:  T*
-bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
-										U16 data_size, U8* data)
-{
-	LLTextureFetchWorker* worker = getWorker(id);
-	bool res = true;
-
-	++mPacketCount;
-	
-	if (!worker)
-	{
-// 		LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL;
-		res = false;
-	}
-	else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK ||
-			 worker->mSentRequest != LLTextureFetchWorker::SENT_SIM)
-	{
-// 		LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id
-// 				<< " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState]
-// 				<< " sent: " << worker->mSentRequest << LL_ENDL;
-		res = false;
-	}
-	else if (worker->mLastPacket != -1)
-	{
-		// check to see if we've gotten this packet before
-// 		LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL;
-		res = false;
-	}
-	else if (!data_size)
-	{
-// 		LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
-		res = false;
-	}
-	if (!res)
-	{
-		mNetworkQueueMutex.lock();										// +Mfnq
-		++mBadPacketCount;
-		mCancelQueue[host].insert(id);
-		mNetworkQueueMutex.unlock();									// -Mfnq 
-		return false;
-	}
-
-	LLViewerStatsRecorder::instance().textureFetch(data_size);
-	LLViewerStatsRecorder::instance().log(0.1f);
-
-	worker->lockWorkMutex();
-
-
-	//	Copy header data into image object
-	worker->mImageCodec = codec;
-	worker->mTotalPackets = packets;
-	worker->mFileSize = (S32)totalbytes;	
-	llassert_always(totalbytes > 0);
-	llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
-	res = worker->insertPacket(0, data, data_size);
-	worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
-	worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
-	worker->unlockWorkMutex();											// -Mw
-	return res;
-}
-
-
-// Threads:  T*
-bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
-{
-	LLTextureFetchWorker* worker = getWorker(id);
-	bool res = true;
-
-	++mPacketCount;
-	
-	if (!worker)
-	{
-// 		LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL;
-		res = false;
-	}
-	else if (worker->mLastPacket == -1)
-	{
-// 		LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL;
-		res = false;
-	}
-	else if (!data_size)
-	{
-// 		LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL;
-		res = false;
-	}
-	if (!res)
-	{
-		mNetworkQueueMutex.lock();										// +Mfnq
-		++mBadPacketCount;
-		mCancelQueue[host].insert(id);
-		mNetworkQueueMutex.unlock();									// -Mfnq
-		return false;
-	}
-	
-	LLViewerStatsRecorder::instance().textureFetch(data_size);
-	LLViewerStatsRecorder::instance().log(0.1f);
-
-	worker->lockWorkMutex();
-
-	
-	res = worker->insertPacket(packet_num, data, data_size);
-	
-	if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||
-		(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
-	{
-		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
-		worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
-	}
-	else
-	{
-// 		LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id
-// 				<< " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL;
-		removeFromNetworkQueue(worker, true); // failsafe
-	}
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	if (packet_num >= (worker->mTotalPackets - 1))
-	{
-		static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
-		static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
-
-		if (log_to_viewer_log || log_to_sim)
-		{
-			U64Microseconds timeNow = LLTimer::getTotalTime();
-			mTextureInfoMainThread.setRequestSize(id, worker->mFileSize);
-			mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow);
-		}
-	}
-#endif
-	worker->unlockWorkMutex();											// -Mw
-
-	return res;
-}
-
 //////////////////////////////////////////////////////////////////////////////
 
 // Threads:  T*
@@ -3750,13 +3179,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
 		request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32();
 		if (worker->mFileSize > 0)
 		{
-			if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR)
-			{
-				S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE;
-				data_size = llmax(data_size, 0);
-				data_progress = (F32)data_size / (F32)worker->mFileSize;
-			}
-			else if (worker->mFormattedImage.notNull())
+			if (worker->mFormattedImage.notNull())
 			{
 				data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize;
 			}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 01c7c7219a634d27e86c7935787e4133b823237d..3ce1b8729f866c7c7845af622a44399f53cc170c 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -101,12 +101,6 @@ class LLTextureFetch final : public LLWorkerThread
 	// Threads:  T*
 	bool updateRequestPriority(const LLUUID& id, F32 priority);
 
-    // Threads:  T*
-	bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
-
-    // Threads:  T*
-	bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
-
     // Threads:  T* (but not safe)
 	void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
 	
@@ -227,12 +221,6 @@ class LLTextureFetch final : public LLWorkerThread
 	// ----------------------------------
 	
 protected:
-	// Threads:  T* (but Ttf in practice)
-	void addToNetworkQueue(LLTextureFetchWorker* worker);
-
-	// Threads:  T*
-	void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
-
     // Threads:  T*
 	void addToHTTPQueue(const LLUUID& id);
 
@@ -251,9 +239,6 @@ class LLTextureFetch final : public LLWorkerThread
 	bool runCondition() override;
 
 private:
-    // Threads:  Tmain
-	void sendRequestListToSimulators();
-	
 	// Threads:  Ttf
 	/*virtual*/ void startThread(void) override;
 	
@@ -319,7 +304,7 @@ class LLTextureFetch final : public LLWorkerThread
 
 private:
 	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only
-	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
+	LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue
 
 	LLTextureCache* mTextureCache;
 	LLImageDecodeThread* mImageDecodeThread;
@@ -330,10 +315,8 @@ class LLTextureFetch final : public LLWorkerThread
 
 	// Set of requests that require network data
 	typedef std::set<LLUUID> queue_t;
-	queue_t mNetworkQueue;												// Mfnq
 	queue_t mHTTPTextureQueue;											// Mfnq
 	typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
-	cancel_queue_t mCancelQueue;										// Mfnq
 	F32 mTextureBandwidth;												// <none>
 	std::atomic<F32> mMaxBandwidth;
 #ifndef LL_RELEASE_FOR_DOWNLOAD
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 16a55dc85658db7d1acf8e5256ea670f4cb9ebb2..b826a5b0b9a67ec8430e4bdb3ce5f4b821daa9cb 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -234,7 +234,6 @@ void LLTextureBar::draw()
 		{ "DSK", LLColor4::cyan },	// LOAD_FROM_TEXTURE_CACHE
 		{ "DSK", LLColor4::blue },	// CACHE_POST
 		{ "NET", LLColor4::green },	// LOAD_FROM_NETWORK
-		{ "SIM", LLColor4::green },	// LOAD_FROM_SIMULATOR
 		{ "HTW", LLColor4::green },	// WAIT_HTTP_RESOURCE
 		{ "HTW", LLColor4::green },	// WAIT_HTTP_RESOURCE2
 		{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 9d14a548f9338394606f38554752c31aa86fa5f4..bf76c98ffeacff25e119bdaaf5bf338c8b8f9ee1 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -44,6 +44,7 @@
 #include "llagent.h"  // HACK for destinations guide on startup
 #include "llfloaterreg.h"  // HACK for destinations guide on startup
 #include "llviewercontrol.h"  // HACK for destinations guide on startup
+#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX
 
 LLToolBarView* gToolBarView = NULL;
 
@@ -357,6 +358,22 @@ bool LLToolBarView::loadToolbars(bool force_default)
 			}
 		}
 	}
+
+    // SL-18581: Don't show the starter avatar toolbar button for NUX users
+    LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
+    if (gAgent.isFirstLogin()
+        && my_outfits_cat != NULL
+        && my_outfits_cat->getDescendentCount() > 0)
+    {
+        for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
+        {
+            if (mToolbars[i])
+            {
+                mToolbars[i]->removeCommand(LLCommandId("avatar"));
+            }
+        }
+    }
+
 	mToolbarsLoaded = true;
 	return true;
 }
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 3f498bfe1b717fc8ff290c5a762266b746d4bda4..288125331a3767da364924052bbead4fda626dd6 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -916,11 +916,6 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
     {
         floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
     }
-    LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
-    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
-    {
-        floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
-    }
 }
 
 //=========================================================================
@@ -1003,11 +998,5 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
             floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
         }
     }
-
-    LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
-    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
-    {
-        floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
-    }
 }
 
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index ea22680fe08f62567f57244e0e76a69129c6dac3..f3a264812ddd1f0c2394ac117061ba8ec4e78d1c 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -505,7 +505,20 @@ void audio_update_listener()
 	if (gAudiop)
 	{
 		// update listener position because agent has moved	
-		LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal();		
+        static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0);
+        LLVector3d ear_position;
+        switch(mEarLocation)
+        {
+        case 0:
+        default:
+            ear_position = gAgentCamera.getCameraPositionGlobal();
+            break;
+
+        case 1:
+            ear_position = gAgent.getPositionGlobal();
+            break;
+        }
+		LLVector3d lpos_global = ear_position;		
 		LLVector3 lpos_global_f;
 		lpos_global_f.setVec(lpos_global);
 	
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 19125c85c40fb6885eacd687c2d96ebe36efd8cb..64417df4b7df437b391db454d65a9f0a0b381d0d 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -655,7 +655,7 @@ bool toggle_show_navigation_panel(const LLSD& newvalue)
 
 	LLNavigationBar::getInstance()->setVisible(value);
 	gSavedSettings.setBOOL("ShowMiniLocationPanel", !value);
-
+    gViewerWindow->reshapeStatusBarContainer();
 	return true;
 }
 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 288c3bd2a78b88dbfc3124e4e4f46ef71ceef557..b9635028ad49a62aa938168a64bac3a5278091f6 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -122,7 +122,7 @@
 #include "llfloaterobjectweights.h"
 #include "llfloateropenobject.h"
 #include "llfloateroutfitphotopreview.h"
-#include "llfloateroutfitsnapshot.h"
+#include "llfloatersimpleoutfitsnapshot.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindingconsole.h"
 #include "llfloaterpathfindinglinksets.h"
@@ -195,6 +195,7 @@
 #include "rlvfloaters.h"
 // [/RLVa:KB]
 // handle secondlife:///app/openfloater/{NAME} URLs
+const std::string FLOATER_PROFILE("profile");
 class LLFloaterOpenHandler : public LLCommandHandler
 {
 public:
@@ -210,7 +211,12 @@ class LLFloaterOpenHandler : public LLCommandHandler
 		}
 
 		const std::string floater_name = LLURI::unescape(params[0].asString());
-		LLFloaterReg::showInstance(floater_name);
+        LLSD key;
+        if (floater_name == FLOATER_PROFILE)
+        {
+            key["id"] = gAgentID;
+        }
+		LLFloaterReg::showInstance(floater_name, key);
 
 		return true;
 	}
@@ -403,7 +409,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
 	LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
 	LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
-    LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
+    LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>);
     //LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
 // [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3)
 	LLFloaterReg::add("search_replace", "floater_search_replace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearchReplace>);
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 14d710353279e7fd56038664723df841249a84f7..d1a3e80dadd2111ea78edd2e390aae9e0847f378 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -48,7 +48,7 @@
 #include "llglheaders.h"
 
 extern LLPipeline gPipeline;
-const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters?
+const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
 
 //-----------------------------------------------------------------------------
 // LLViewerJointAttachment()
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index f1bcfb1a35c63c4ec20375b267a44aadf19b37b8..f2103ae52d62fee7386f1aed1135b8abd9ce03fb 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -3702,7 +3702,20 @@ void LLViewerMediaImpl::calculateInterest()
 			LLVector3d global_delta = agent_global - obj_global ;
 			mProximityDistance = global_delta.magVecSquared();  // use distance-squared because it's cheaper and sorts the same.
 
-			LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global;
+            static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0);
+            LLVector3d ear_position;
+            switch(mEarLocation)
+            {
+            case 0:
+            default:
+                ear_position = gAgentCamera.getCameraPositionGlobal();
+                break;
+
+            case 1:
+                ear_position = agent_global;
+                break;
+            }
+            LLVector3d camera_delta = ear_position - obj_global;
 			mProximityCamera = camera_delta.magVec();
 		}
 	}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 60d01aaced253a189e5a289cd125f5da0adc4f0a..47b4206d0a9ceea94a8135eeaa79294498d5e195 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4359,7 +4359,10 @@ class LLLandSit : public view_listener_t
 		if ( (rlv_handler_t::isEnabled()) && ((!RlvActions::canStand()) || (gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) )
 			return true;
 // [/RLVa:KB]
-
+        if (gAgent.isSitting())
+        {
+            gAgent.standUp();
+        }
         LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
 
         LLQuaternion target_rot;
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 0055794db675358bd43bca2ac68a5c3af73c1d14..fc8dfe5d8be7c5ad81d3e1ab3087b2ae62675297 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -38,7 +38,7 @@
 #include "llfloatermap.h"
 #include "llfloatermodelpreview.h"
 #include "llfloatersnapshot.h"
-#include "llfloateroutfitsnapshot.h"
+#include "llfloatersimpleoutfitsnapshot.h"
 #include "llimage.h"
 #include "llimagebmp.h"
 #include "llimagepng.h"
@@ -648,7 +648,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t
 	bool handleEvent(const LLSD& userdata) override
     {
 		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
-		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
+		LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
 		bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
 			|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
 		bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
@@ -665,7 +665,7 @@ class LLFileCloseAllWindows : public view_listener_t
 		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
 		if (floater_snapshot)
 			floater_snapshot->closeFloater(app_quitting);
-		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
+        LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance();
 		if (floater_outfit_snapshot)
 			floater_outfit_snapshot->closeFloater(app_quitting);
 		if (gMenuHolder) gMenuHolder->hideMenus();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index ab6e6e33b0db3c3bb651a1fe1f05d931154711ed..8524ac401f8f670272e82d36c59fa0d323a816f7 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -324,7 +324,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mLastUpdateCached(FALSE),
 	mExtraParameterList(LLNetworkData::PARAMS_MAX >> 4),
 	mCachedMuteListUpdateTime(0),
-	mCachedOwnerInMuteList(false)
+	mCachedOwnerInMuteList(false),
+	mRiggedAttachedWarned(false)
 {
 	if (!is_global)
 	{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index e5e946ce62a1d789a80be0315fd5c752f8968323..26f46a29ade27474309b6fbe079ed4de27d568ea 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -750,6 +750,8 @@ class LLViewerObject
 	// Replace textures with web pages on this object while drawing
 	BOOL mRenderMedia;
 
+    bool mRiggedAttachedWarned;
+
 	// In bits
 	S32				mBestUpdatePrecision;
 
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index a545463d98c6bb51e1b21a2de9fd69970c5f1202..a5d1121b295dc41a311fce91aa83c6a59935e00e 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -2001,7 +2001,7 @@ void LLViewerParcelMgr::optionallyStartMusic(const std::string &music_url, const
 		static LLCachedControl<bool> tentative_autoplay(gSavedSettings, "MediaTentativeAutoPlay", true);
 		// only play music when you enter a new parcel if the UI control for this
 		// was not *explicitly* stopped by the user. (part of SL-4878)
-		LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
+		LLPanelNearByMedia* nearby_media_panel = gStatusBar ? gStatusBar->getNearbyMediaPanel() : NULL;
         LLViewerAudio* viewer_audio = LLViewerAudio::getInstance();
 
         // ask mode //todo constants
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index b39816b781702700a640768889a0690cc091980c..ae42847f690b0d98dbbc1c9cc5e1fd1da3654733 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -44,11 +44,13 @@
 #include "llxmltree.h"
 #include "message.h"
 
+#include "lldrawpoolbump.h" // to init bumpmap images
 #include "lltexturecache.h"
 #include "lltexturefetch.h"
 #include "llviewercontrol.h"
 #include "llviewertexture.h"
 #include "llviewermedia.h"
+#include "llviewernetwork.h"
 #include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "pipeline.h"
@@ -142,9 +144,6 @@ void LLViewerTextureList::doPreloadImages()
 	//uv_test->setClamp(FALSE, FALSE);
 	//uv_test->setMipFilterNearest(TRUE, TRUE);
 
-	// prefetch specific UUIDs
-	LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
-	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
 	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
@@ -163,12 +162,6 @@ void LLViewerTextureList::doPreloadImages()
 		image->setAddressMode(LLTexUnit::TAM_WRAP);
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
-	if (image) 
-	{
-		image->setAddressMode(LLTexUnit::TAM_WRAP);	
-		mImagePreloads.insert(image);
-	}
 	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
 		0, 0, IMG_TRANSPARENT);
 	if (image) 
@@ -206,7 +199,18 @@ void LLViewerTextureList::doPreloadImages()
 
 static std::string get_texture_list_name()
 {
-	return gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
+    if (LLGridManager::getInstance()->isInProductionGrid())
+    {
+        return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
+            "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml");
+    }
+    else
+    {
+        const std::string& grid_id_str = LLGridManager::getInstance()->getGridId();
+        const std::string& grid_id_lower = utf8str_tolower(grid_id_str);
+        return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
+            "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml");
+    }
 }
 
 void LLViewerTextureList::doPrefetchImages()
@@ -215,6 +219,26 @@ void LLViewerTextureList::doPrefetchImages()
 	gTextureTimer.start();
 	gTextureTimer.pause();
 
+    // todo: do not load without getViewerAssetUrl()
+    // either fail login without caps or provide this
+    // in some other way, textures won't load otherwise
+    LLViewerFetchedTexture *imagep = findImage(DEFAULT_WATER_NORMAL, TEX_LIST_STANDARD);
+    if (!imagep)
+    {
+        // add it to mImagePreloads only once
+        imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+        if (imagep)
+        {
+            imagep->setAddressMode(LLTexUnit::TAM_WRAP);
+            mImagePreloads.insert(imagep);
+        }
+    }
+
+    LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
+    LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
+
+    LLStandardBumpmap::addstandard();
+
 	if (LLAppViewer::instance()->getPurgeCache())
 	{
 		// cache was purged, no point
@@ -1528,152 +1552,6 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// static
-void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data)
-{
-	static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-
-	// Receive image header, copy into image object and decompresses 
-	// if this is a one-packet image. 
-	
-	LLUUID id;
-	
-	char ip_string[256];
-	u32_to_ip_string(msg->getSenderIP(),ip_string);
-	
-	U32Bytes received_size ;
-	if (msg->getReceiveCompressedSize())
-	{
-		received_size = (U32Bytes)msg->getReceiveCompressedSize() ;		
-	}
-	else
-	{
-		received_size = (U32Bytes)msg->getReceiveSize() ;		
-	}
-	add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size);
-	add(LLStatViewer::TEXTURE_PACKETS, 1);
-	
-	U8 codec;
-	U16 packets;
-	U32 totalbytes;
-	msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
-	msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec);
-	msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets);
-	msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes);
-	
-	S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); 
-	if (!data_size)
-	{
-		return;
-	}
-	if (data_size < 0)
-	{
-		// msg->getSizeFast() is probably trying to tell us there
-		// was an error.
-		LL_ERRS() << "image header chunk size was negative: "
-		<< data_size << LL_ENDL;
-		return;
-	}
-	
-	// this buffer gets saved off in the packet list
-	U8 *data = new U8[data_size];
-	msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
-	
-	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-	if (!image)
-	{
-		delete [] data;
-		return;
-	}
-	if(log_texture_traffic)
-	{
-		gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
-	}
-
-	//image->getLastPacketTimer()->reset();
-	bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data);
-	if (!res)
-	{
-		delete[] data;
-	}
-}
-
-// static
-void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
-{
-	static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
-
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
-	
-	// Receives image packet, copy into image object,
-	// checks if all packets received, decompresses if so. 
-	
-	LLUUID id;
-	U16 packet_num;
-	
-	char ip_string[256];
-	u32_to_ip_string(msg->getSenderIP(),ip_string);
-	
-	U32Bytes received_size ;
-	if (msg->getReceiveCompressedSize())
-	{
-		received_size = (U32Bytes)msg->getReceiveCompressedSize() ;
-	}
-	else
-	{
-		received_size = (U32Bytes)msg->getReceiveSize() ;		
-	}
-
-	add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size));
-	add(LLStatViewer::TEXTURE_PACKETS, 1);
-	
-	//llprintline("Start decode, image header...");
-	msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
-	msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num);
-	S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); 
-	
-	if (!data_size)
-	{
-		return;
-	}
-	if (data_size < 0)
-	{
-		// msg->getSizeFast() is probably trying to tell us there
-		// was an error.
-		LL_ERRS() << "image data chunk size was negative: "
-		<< data_size << LL_ENDL;
-		return;
-	}
-	if (data_size > MTUBYTES)
-	{
-		LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL;
-		return;
-	}
-	U8 *data = new U8[data_size];
-	msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
-	
-	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-	if (!image)
-	{
-		delete [] data;
-		return;
-	}
-	if(log_texture_traffic)
-	{
-		gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ;
-	}
-
-	//image->getLastPacketTimer()->reset();
-	bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data);
-	if (!res)
-	{
-		delete[] data;
-	}
-}
-
-
 // We've been that the asset server does not contain the requested image id.
 // static
 void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data)
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 85f5d1064aa1f1f2b6e29ff553ec63aa21ef4516..a797b6f70cdcdd1506c03533520d686a287fc0eb 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -111,8 +111,6 @@ class LLViewerTextureList
                                  const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
 	static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
 	static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
-	static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
-	static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
 
 public:
 	LLViewerTextureList();
@@ -146,7 +144,9 @@ class LLViewerTextureList
 
 	void updateMaxResidentTexMem(S32Megabytes mem);
 	
+    // Local UI images
 	void doPreloadImages();
+    // Network images. Needs caps and cache to work
 	void doPrefetchImages();
 
 	void clearFetchingRequests();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 06b1eb0e927fcc8d28262b6a1bb474f50c4b98b5..58333fbb689148d9644f18731e77014a8363db5f 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -267,6 +267,8 @@ static const F32 MIN_UI_SCALE = 0.75f;
 static const F32 MAX_UI_SCALE = 7.0f;
 static const F32 MIN_DISPLAY_SCALE = 0.75f;
 
+static const char KEY_MOUSELOOK = 'M';
+
 LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity");
 
 
@@ -2270,31 +2272,36 @@ void LLViewerWindow::initWorldUI()
 	// Force gFloaterTools to initialize
 	LLFloaterReg::getInstance("build");
 
-
 	// Status bar
 	LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
 	gStatusBar = new LLStatusBar(status_bar_container->getLocalRect());
-	gStatusBar->setFollowsAll();
+	gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT);
 	gStatusBar->setShape(status_bar_container->getLocalRect());
 	// sync bg color with menu bar
 	gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
     // add InBack so that gStatusBar won't be drawn over menu
-	status_bar_container->addChildInBack(gStatusBar);
-	status_bar_container->setVisible(TRUE);
+    status_bar_container->addChildInBack(gStatusBar, 2/*tab order, after menu*/);
+    status_bar_container->setVisible(TRUE);
 
 	// Navigation bar
-	LLPanel* nav_bar_container = getRootView()->getChild<LLPanel>("nav_bar_container");
+	LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container");
 
 	LLNavigationBar* navbar = LLNavigationBar::getInstance();
 	navbar->setShape(nav_bar_container->getLocalRect());
 	navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
 	nav_bar_container->addChild(navbar);
 	nav_bar_container->setVisible(TRUE);
-	
+
+
 	if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
 	{
 		navbar->setVisible(FALSE);
 	}
+    else
+    {
+        reshapeStatusBarContainer();
+    }
+
 
 	// Top Info bar
 	LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
@@ -2901,6 +2908,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
     if (keyboard_focus
         && !gFocusMgr.getKeystrokesOnly())
     {
+        //Most things should fall through, but mouselook is an exception,
+        //don't switch to mouselook if any floater has focus
+        if ((key == KEY_MOUSELOOK) && !(mask & (MASK_CONTROL | MASK_ALT)))
+        {
+            return TRUE;
+        }
+
         LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(keyboard_focus);
         if (cur_focus && cur_focus->acceptsTextInput())
         {
@@ -6134,6 +6148,27 @@ LLRect LLViewerWindow::getChatConsoleRect()
 
 	return console_rect;
 }
+
+void LLViewerWindow::reshapeStatusBarContainer()
+{
+    LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
+    LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container");
+
+    S32 new_height = status_bar_container->getRect().getHeight();
+    S32 new_width = status_bar_container->getRect().getWidth();
+
+    if (gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
+    {
+        // Navigation bar is outside visible area, expand status_bar_container to show it
+        new_height += nav_bar_container->getRect().getHeight();
+    }
+    else
+    {
+        // collapse status_bar_container
+        new_height -= nav_bar_container->getRect().getHeight();
+    }
+    status_bar_container->reshape(new_width, new_height, TRUE);
+}
 //----------------------------------------------------------------------------
 
 
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 6086180d535e290068cdfd4153de2e1c72c8d21b..95b5594e7cde39a6188c443b194cb61aa3ed4975 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -176,6 +176,8 @@ class LLViewerWindow final : public LLWindowCallbacks
 	bool			getUIVisibility();
 	void			handlePieMenu(S32 x, S32 y, MASK mask);
 
+    void            reshapeStatusBarContainer();
+
 	BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
 
 	//
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index bd873cf4731074b2823f8c09c23d50021997a299..ac13e2b4638736ea635d2b3f1a95cdbbc5a4c8e1 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -287,6 +287,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 			BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ;
 			if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
 			{
+                if (mDetailTextures[i]->getDecodePriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage())
+                {
+                    mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP);
+                    mDetailTextures[i]->forceToRefetchTexture(ddiscard);
+                }
+
 				if(delete_raw)
 				{
 					mDetailTextures[i]->destroyRawImage() ;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 086d8b3808fc109dd6b3924c37d5ff31612657f5..9c0ca4a0e23764980217ff701d2c38b0414c1eec 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -11010,7 +11010,7 @@ void LLVOAvatar::updateVisualComplexity()
 // with an avatar. This will be either an attached object or an animated
 // object.
 void LLVOAvatar::accountRenderComplexityForObject(
-    const LLViewerObject *attached_object,
+    LLViewerObject *attached_object,
     const F32 max_attachment_complexity,
     LLVOVolume::texture_cost_t& textures,
     U32& cost,
@@ -11093,7 +11093,7 @@ void LLVOAvatar::accountRenderComplexityForObject(
                     && attached_object->mDrawable)
                 {
                     textures.clear();
-
+                    BOOL is_rigged_mesh = attached_object->isRiggedMesh();
         mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
 
                     const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
@@ -11112,6 +11112,7 @@ void LLVOAvatar::accountRenderComplexityForObject(
                         LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
                         for (LLViewerObject* childp : child_list)
                         {
+                            is_rigged_mesh |= childp->isRiggedMesh();
                             const LLVOVolume* chld_volume = childp ? childp->asVolume() : nullptr;
                             if (chld_volume)
                             {
@@ -11120,6 +11121,16 @@ void LLVOAvatar::accountRenderComplexityForObject(
                                 hud_object_complexity.objectsCount++;
                             }
                         }
+                        if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
+                        {
+                            LLSD args;                            
+                            LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
+                            args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
+                            args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
+                            LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
+
+                            attached_object->mRiggedAttachedWarned = true;
+                        }
 
                         hud_object_complexity.texturesCount += textures.size();
 
@@ -11230,13 +11241,13 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 #if SLOW_ATTACHMENT_LIST
 		for (const auto& attach_pair : mAttachmentPoints)
 		{
-			const LLViewerJointAttachment* attachment = attach_pair.second;
-			for (const LLViewerObject* attached_object : attachment->mAttachedObjects)
+			LLViewerJointAttachment* attachment = attach_pair.second;
+			for (LLViewerObject* attached_object : attachment->mAttachedObjects)
 			{
 #else
 		for(auto& iter : mAttachedObjectsVector)
 		{{
-				const LLViewerObject* attached_object = iter.first;
+                LLViewerObject* attached_object = iter.first;
 #endif
                 accountRenderComplexityForObject(attached_object, max_attachment_complexity,
                                                  textures, cost, hud_complexity_list, item_complexity, temp_item_complexity);
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3071e3da87cc889271455e4c1c1ea39d8cd9279c..b0bbcf802f6d326bcd8d919089d19442c0495808 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -299,7 +299,7 @@ class LLVOAvatar :
 	void			addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses = false);
 	void 			idleUpdateRenderComplexity();
 	void 			idleUpdateDebugInfo();
-    void 			accountRenderComplexityForObject(const LLViewerObject *attached_object,
+    void 			accountRenderComplexityForObject(LLViewerObject *attached_object,
                                                      const F32 max_attachment_complexity,
                                                      LLVOVolume::texture_cost_t& textures,
                                                      U32& cost,
diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h
index 21edc261c9f3c46247263f2a8615a9a2bc18dde9..697bc1dac3a229a5485c7ebbd84181d651376c07 100644
--- a/indra/newview/llvoground.h
+++ b/indra/newview/llvoground.h
@@ -49,7 +49,6 @@ class LLVOGround final : public LLStaticViewerObject
 	/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
 	/*virtual*/ BOOL		updateGeometry(LLDrawable *drawable);
 
-	void cleanupGL();
 };
 
 #endif // LL_LLVOGROUND_H
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index f42bca727a66b2255285cd3d413cbffe36574e69..6d902f92a2441c443bb52189817eda599983d188 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1272,8 +1272,8 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
 
         if (result.has("connector"))
         {
-            LLVoiceVivoxStats::getInstance()->establishAttemptEnd(connected);
             connected = LLSD::Boolean(result["connector"]);
+            LLVoiceVivoxStats::getInstance()->establishAttemptEnd(connected);
             if (!connected)
             {
                 if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX && !sShuttingDown)
@@ -4592,9 +4592,7 @@ void LLVivoxVoiceClient::messageEvent(
 						IM_NOTHING_SPECIAL,		// default arg
 						0,						// default arg
 						LLUUID::null,			// default arg
-						LLVector3::zero,		// default arg
-						true);					// prepend name and make it a link to the user's profile
-
+						LLVector3::zero);		// default arg
 			}
 		}		
 	}
@@ -6250,7 +6248,7 @@ void LLVivoxVoiceClient::clearSessionHandle(const sessionStatePtr_t session)
 {
     if (session)
     {
-        if (session->mHandle.empty())
+        if (!session->mHandle.empty())
         {
             sessionMap::iterator iter = mSessionsByHandle.find(session->mHandle);
             if (iter != mSessionsByHandle.end())
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index af24e410fd922750acd5f30bf4881b3a439d5d47..aab4bab3316e6e844ece279f157babbccb074f9e 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -98,7 +98,7 @@ LLWorld::LLWorld() :
 	mLastPacketsLost(0),
 	mSpaceTimeUSec(0)
 {
-	for (S32 i = 0; i < 8; i++)
+	for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++)
 	{
 		mEdgeWaterObjects[i] = NULL;
 	}
@@ -131,7 +131,7 @@ void LLWorld::resetClass()
 	LLViewerPartSim::getInstance()->destroyClass();
 
 	mDefaultWaterTexturep = NULL ;
-	for (S32 i = 0; i < 8; i++)
+	for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++)
 	{
 		mEdgeWaterObjects[i] = NULL;
 	}
@@ -789,6 +789,8 @@ void LLWorld::clearAllVisibleObjects()
 		//clear all cached visible objects.
 		(*iter)->clearCachedVisibleObjects();
 	}
+    clearHoleWaterObjects();
+    clearEdgeWaterObjects();
 }
 
 void LLWorld::refreshLimits()
@@ -976,7 +978,7 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc
     }
 
 	S32 dir;
-	for (dir = 0; dir < 8; dir++)
+	for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++)
 	{
 		LLVOWater* waterp = mEdgeWaterObjects[dir];
 		if (waterp && waterp->mDrawable)
@@ -987,6 +989,26 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc
 	}
 }
 
+void LLWorld::clearHoleWaterObjects()
+{
+    for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin();
+        iter != mHoleWaterObjects.end(); ++iter)
+    {
+        LLVOWater* waterp = (*iter).get();
+        gObjectList.killObject(waterp);
+    }
+    mHoleWaterObjects.clear();
+}
+
+void LLWorld::clearEdgeWaterObjects()
+{
+    for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++)
+    {
+        gObjectList.killObject(mEdgeWaterObjects[i]);
+        mEdgeWaterObjects[i] = NULL;
+    }
+}
+
 void LLWorld::updateWaterObjects()
 {
 	if (!gAgent.getRegion())
@@ -1030,11 +1052,7 @@ void LLWorld::updateWaterObjects()
 		}
 	}
 
-	for (LLVOWater* waterp : mHoleWaterObjects)
-	{
-		gObjectList.killObject(waterp);
-	}
-	mHoleWaterObjects.clear();
+    clearHoleWaterObjects();
 
 	// Use the water height of the region we're on for areas where there is no region
 	F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f;
@@ -1076,7 +1094,7 @@ void LLWorld::updateWaterObjects()
         512 - ((S32)region_y - min_y) };
 		
 	S32 dir;
-	for (dir = 0; dir < 8; dir++)
+	for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++)
 	{
 		S32 dim[2] = { 0 };
 		switch (gDirAxes[dir][0])
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 74cf88ea7915c89554b8c19158e0b8fd5f4b290f..f0450ab680d98215d042acfa68406d8473aab97f 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -142,12 +142,9 @@ class LLWorld final : public LLSimpleton<LLWorld>
 	void					updateRegions(F32 max_update_time);
 	void					updateVisibilities();
 	void					updateParticles();
-	void					updateClouds(const F32 dt);
-	LLCloudGroup *			findCloudGroup(const LLCloudPuff &puff);
 
 	void					renderPropertyLines();
 
-	void resetStats();
 	void updateNetStats(); // Update network statistics for all the regions...
 
 	void printPacketsLost();
@@ -160,7 +157,7 @@ class LLWorld final : public LLSimpleton<LLWorld>
 	void setLandFarClip(const F32 far_clip);
 
 	LLViewerTexture *getDefaultWaterTexture();
-	void updateWaterObjects();
+    void updateWaterObjects();
 
     void precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water);
 
@@ -216,6 +213,9 @@ class LLWorld final : public LLSimpleton<LLWorld>
 	bool isRegionListed(const LLViewerRegion* region) const;
 
 private:
+    void clearHoleWaterObjects();
+    void clearEdgeWaterObjects();
+
 	region_list_t	mActiveRegionList;
 	region_list_t	mRegionList;
 	region_list_t	mVisibleRegionList;
@@ -248,15 +248,14 @@ class LLWorld final : public LLSimpleton<LLWorld>
 	U32 mNumOfActiveCachedObjects;
 	U64MicrosecondsImplicit mSpaceTimeUSec;
 
-	BOOL mClassicCloudsEnabled;
-
 	////////////////////////////
 	//
 	// Data for "Fake" objects
 	//
 
 	std::list<LLPointer<LLVOWater> > mHoleWaterObjects;
-	LLPointer<LLVOWater> mEdgeWaterObjects[8];
+    static const S32 EDGE_WATER_OBJECTS_COUNT = 8;
+    LLPointer<LLVOWater> mEdgeWaterObjects[EDGE_WATER_OBJECTS_COUNT];
 
 	LLPointer<LLViewerTexture> mDefaultWaterTexturep;
 };
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 30f13790af0318e78bb441155969dd699af47adf..20d860dba2ffc531342e80dfa1e386fba908dbcb 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -725,7 +725,9 @@ void LLPipeline::cleanup()
 
 	mFaceSelectImagep = NULL;
 
-	mMovedBridge.clear();
+    mMovedList.clear();
+    mMovedBridge.clear();
+    mShiftList.clear();
 
 	mInitialized = false;
 
@@ -1988,20 +1990,20 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-	for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
-		 iter != gPipeline.mNearbyLights.end();)
-	{
-		if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
-		{
-			auto cur_iter = iter++;
-			gPipeline.mLights.erase(cur_iter->drawable);
-			gPipeline.mNearbyLights.erase(cur_iter);
-		}
-		else
-		{
-			++iter;
-		}
-	}
+    light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
+
+    while (iter != gPipeline.mNearbyLights.end())
+    {
+        if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
+        {
+            gPipeline.mLights.erase(iter->drawable);
+            iter = gPipeline.mNearbyLights.erase(iter);
+        }
+        else
+        {
+            iter++;
+        }
+    }
 }
 
 U32 LLPipeline::addObject(LLViewerObject *vobj)
@@ -3005,6 +3007,14 @@ void LLPipeline::clearRebuildDrawables()
 		drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
 	}
 	mMovedList.clear();
+
+    for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+        iter != mShiftList.end(); ++iter)
+    {
+        LLDrawable *drawablep = *iter;
+        drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD | LLDrawable::ON_SHIFT_LIST);
+    }
+    mShiftList.clear();
 }
 
 void LLPipeline::rebuildPriorityGroups()
@@ -11183,6 +11193,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
         if (preview_avatar)
         {
             // Only show rigged attachments for preview
+            // For the sake of performance and so that static
+            // objects won't obstruct previewing changes
 #if SLOW_ATTACHMENT_LIST
 			for (const auto& attach_pair : avatar->mAttachmentPoints)
             {
@@ -11195,9 +11207,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
 			{{
 				LLViewerObject* attached_object = attachment_iter->first;
 #endif
-                    if (attached_object && attached_object->isRiggedMesh())
+                    if (attached_object)
                     {
-                        markVisible(attached_object->mDrawable->getSpatialBridge(), viewer_camera);
+                        if (attached_object->isRiggedMesh())
+                        {
+                            markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+                        }
+                        else
+                        {
+                            // sometimes object is a linkset and rigged mesh is a child
+                            LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+                            for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+                                iter != child_list.end(); iter++)
+                            {
+                                LLViewerObject* child = *iter;
+                                if (child->isRiggedMesh())
+                                {
+                                    markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+                                    break;
+                                }
+                            }
+                        }
                     }
                 }
             }
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index afae90d3edcabeadfcc64309266e553fa53e7797..72401e1050e96c21fb51a3d82c150355a3b2111c 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -468,7 +468,7 @@ class LLPipeline
         RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
 		RENDER_TYPE_PASS_GRASS					= LLRenderPass::PASS_GRASS,
 		RENDER_TYPE_PASS_FULLBRIGHT				= LLRenderPass::PASS_FULLBRIGHT,
-        RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT,
+        RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED,
 		RENDER_TYPE_PASS_INVISIBLE				= LLRenderPass::PASS_INVISIBLE,
         RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED,
 		RENDER_TYPE_PASS_INVISI_SHINY			= LLRenderPass::PASS_INVISI_SHINY,
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 15e45944590c25c7a2ac4109e508ed1e26d25e39..daa75472a7e228d8499c65cdf87296c6ae7ef094 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -1008,7 +1008,12 @@
   <color
     name="AddPaymentPanel"
     value="0.27 0.27 0.27 1" />
-
+  <color
+    name="OutfitSnapshotMacMask"
+    value="0.115 0.115 0.115 1"/>
+ <color
+   name="OutfitSnapshotMacMask2"
+   value="0.1 0.1 0.1 1"/>
   <!-- Alchemy -->
   <color
    name="AvatarListItemOnlineColor"
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index e89505449d78ebb42074d7b64a97e60fcc07f598..baa335d427ad272b0d553cf76a29c2263fafb4b6 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1943,7 +1943,7 @@ Only large parcels can be listed in search.
             </text>
             <check_box
              height="16"
-             label="Obscure MOAP"
+             label="Restrict MOAP to this parcel"
              layout="topleft"
              left="110"
              left_pad="0"
diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml
index baff8e1bc065ad3cdcb90d7be0c6965f131a5fd2..19e42798af7a65c1d9f3ebfe804474d08c37cb57 100644
--- a/indra/newview/skins/default/xui/en/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/en/floater_how_to.xml
@@ -3,7 +3,6 @@
   legacy_header_height="18"
   can_resize="false"
   can_minimize="false"
-  can_close="false"
   height="525"
   layout="topleft"
   name="floater_how_to"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 86d27116358dfb2c679813c058fedbb162a5378f..97f6360e524893ec4cca51f5057099662e1c24cd 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -430,20 +430,6 @@
                          left="1"
                          right="-1"
                          bottom="-1">
-                            <layout_panel
-                             auto_resize="false"
-                             height="26"
-                             name="translate_chat_checkbox_lp">
-                                <check_box
-                                 top="10"
-                                 control_name="TranslateChat"
-                                 enabled="true"
-                                 height="16"
-                                 label="Translate chat"
-                                 left="5"
-                                 name="translate_chat_checkbox"
-                                 width="230" />
-                            </layout_panel>
                             <layout_panel
                              name="chat_holder">
                                 <chat_history
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
deleted file mode 100644
index 15c480f144777e18527f117714b0debd7fc1a2e7..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
+++ /dev/null
@@ -1,351 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- legacy_header_height="18"
- can_minimize="true"
- can_resize="false"
- can_close="true"
- height="455"
- layout="topleft"
- name="outfit_snapshot"
- single_instance="true"
- help_topic="snapshot"
- save_rect="true"
- save_visibility="false"
- title="OUTFIT SNAPSHOT"
- width="624"
- min_height="455">
-  <floater.string
-   name="unknown">
-    unknown
-  </floater.string>
-  <string
-   name="inventory_progress_str">
-    Saving to Inventory
-  </string>
-  <string
- 	 name="inventory_succeeded_str">
-    Saved to Inventory!
-  </string>
-  <string
- 	 name="inventory_failed_str">
-    Failed to save to inventory.
-  </string>
-  <button
-     follows="left|top"
-     height="25"
-     image_overlay="Refresh_Off"
-	 image_hover_unselected="Toolbar_Middle_Over"
-     image_selected="Toolbar_Middle_Selected"
-     image_unselected="Toolbar_Middle_Off"
-     image_overlay_alignment="left"
-     imgoverlay_label_space="5"
-	 pad_bottom="0"
-	 halign="left"
-     layout="topleft"
-     left="10"
-	 label="REFRESH"
-     name="new_snapshot_btn"
-     top_pad="26"
-     width="167" />
-	<button
-       follows="left|top"
-	   control_name="AdvanceOutfitSnapshot"
-	   invisibility_control="AdvanceOutfitSnapshot"
-       height="25"
-	   is_toggle="true"
-       layout="topleft"
-	   image_hover_unselected="Toolbar_Middle_Over"
-	   image_selected="Toolbar_Middle_Off"
-	   image_unselected="Toolbar_Middle_Off"
-	   image_overlay="Conv_toolbar_expand"
-       name="retract_btn"
-       left_pad="1"
-	   top_delta="0"
-       width="31" />
-   <button
-       follows="left|top"
-	   control_name="AdvanceOutfitSnapshot"
-	   visibility_control="AdvanceOutfitSnapshot"
-       height="25"
-	   is_toggle="true"
-       layout="topleft"
-	   image_overlay="Conv_toolbar_collapse"
-	   image_hover_unselected="Toolbar_Middle_Over"
-	   image_selected="Toolbar_Middle_Off"
-	   image_unselected="Toolbar_Middle_Off"
-       name="extend_btn"
-       left_delta="0"
-	   top_delta="0"
-       width="31" />
-	<panel
-     height="154"
-     layout="topleft"
-	 follows="top|left"
-     left="0"
-     name="advanced_options_panel"
-     top_pad="-6"
-     width="210">
-        <view_border 
-         bevel_style="in"
-         follows="left|top|right" 
-         height="1"
-         left="10"
-         layout="topleft"
-         name="advanced_options_hr"
-         right="-1"
-         top_pad="5"
-         />
-        <text
-         type="string"
-         length="1"
-         follows="left|top"
-         height="13"
-         layout="topleft"
-         left="10"
-         name="layer_type_label"
-         top_pad="10"
-         width="100">
-            Capture:
-        </text>
-        <check_box
-         label="Interface"
-         layout="topleft"
-         left="30"
-		 height="16"
-         top_pad="8"
-         width="180"
-         name="ui_check" />
-        <check_box
-         label="HUDs"
-         layout="topleft"
-		 height="16"
-         left="30"
-         top_pad="1"
-         width="180"
-         name="hud_check" />
-        <check_box
-         label="Freeze frame (fullscreen)"
-         layout="topleft"
-		 height="16"
-         left="10"
-         top_pad="1"
-         width="180"
-         name="freeze_frame_check" />
-        <check_box
-         label="Auto-refresh"
-         layout="topleft"
-		 height="16"
-         left="10"
-         top_pad="1"
-         width="180"
-         name="auto_snapshot_check" />
-        <text
-         type="string"
-         length="1"
-         follows="left|top"
-         height="13"
-         layout="topleft"
-         left="10"
-         name="filter_list_label"
-         top_pad="10"
-         width="50">
-            Filter:
-        </text>
-        <combo_box
-            control_name="PhotoFilters"
-            follows="left|right|top"
-            name="filters_combobox"
-            tool_tip="Image filters"
-            top_delta="-3"
-            left="50"
-			right="-1"
-            height="21"
-            width="135">
-            <combo_box.item
-            label="No Filter"
-            name="NoFilter"
-            value="NoFilter" />
-        </combo_box>
-		 <view_border 
-         bevel_style="in"
-         follows="left|top|right" 
-         height="1"
-         left="10"
-         layout="topleft"
-         name="advanced_options_hr"
-         right="-1"
-         top_pad="7"
-         />
-    </panel>
-      <panel
-        class="llpaneloutfitsnapshotinventory"
-        follows="left|top"
-        height="230"
-        layout="topleft"
-        left="0"
-        name="panel_outfit_snapshot_inventory"
-        filename="panel_outfit_snapshot_inventory.xml"
-        top_pad="10"
-        width="215"
-      />
-	<view_border 
-         bevel_style="in"
-         follows="left|top" 
-         height="1"
-         left="10"
-         layout="topleft"
-         name="status_hr"
-         width="199"
-         top_pad="-16"/>
-	<panel
-       background_visible="false"
-       follows="left|top"
-       font="SansSerifLarge"
-       halign="center"
-       height="20"
-       layout="topleft"
-       left="10"
-       length="1"
-       name="succeeded_panel"
-	   width="198"
-       top_pad="1"
-       type="string"
-       visible="false">
-          <text
-           follows="all"
-           font="SansSerif"
-           halign="center"
-           height="18"
-           layout="topleft"
-           left="1"
-           length="1"
-           name="succeeded_lbl"
-           right="-1"
-           text_color="0.2 0.85 0.2 1"
-           top="4"
-           translate="false"
-           type="string">
-              Succeeded
-          </text>
-      </panel>
-      <panel
-       background_visible="false"
-       follows="left|top"
-       font="SansSerifLarge"
-       halign="center"
-       height="20"
-       layout="topleft"
-       left="10"
-       length="1"
-       name="failed_panel"
-	   width="198"
-       top_delta="0"
-       type="string"
-       visible="false">
-          <text
-           follows="all"
-           font="SansSerif"
-           halign="center"
-           height="18"
-           layout="topleft"
-           left="1"
-           length="1"
-           name="failed_lbl"
-           right="-1"
-           text_color="0.95 0.4 0.4 1"
-           top="4"
-           translate="false"
-           type="string">
-              Failed
-          </text>
-      </panel>
-      <loading_indicator
-       follows="left|top"
-       height="24"
-       layout="topleft"
-       name="working_indicator"
-       left="10"
-       top_delta="0"
-       visible="false"
-       width="24" />
-      <text
-       follows="left|top"
-       font="SansSerifBold"
-       height="14"
-       layout="topleft"
-       left_pad="3"
-       length="1"
-       halign="left"
-       name="working_lbl"
-       top_delta="5"
-       translate="false"
-       type="string"
-       visible="false"
-       width="162">
-          Working
-      </text>
-      <text
-       follows="left|top"
-       font="SansSerifBold"
-       halign="left"
-       height="18"
-       layout="topleft"
-       left="10"
-       length="1"
-       name="refresh_lbl"
-       text_color="0.95 0.4 0.4 1"
-       top_delta="0"
-       translate="false"
-       type="string"
-       visible="false"
-       width="130">
-          Refresh to save.
-      </text>
-  <ui_ctrl 
-    layout="topleft"
-    name="thumbnail_placeholder"
-    top="23"
-	left="215"
-	width="400"
-	height="400"
-    follows="top|left"/>
-  <view_border 
-   bevel_style="in" 
-   height="21"
-   layout="topleft"
-   name="img_info_border"
-   top_pad="0"
-   right="-10"
-   follows="left|top|right"
-   left_delta="0"/>
-   <text
-    type="string"
-    font="SansSerifSmall"
-    length="1"
-    follows="left|top|right"
-    height="14"
-    layout="topleft"
-    left="220"
-	right="-20"
-    halign="left"
-    name="image_res_text"
-    top_delta="5"
-    width="200">
-       [WIDTH]px (width) x [HEIGHT]px (height)
-   </text>
-   <text
-    follows="right|top"
-    font="SansSerifSmall"
-    height="14"
-    layout="topleft"
-    left="-65"
-    length="1"
-    halign="right"
-    name="file_size_label"
-    top_delta="0"
-    type="string"
-    width="50">
-       [SIZE] KB
-   </text>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5ece7b85d583842c84d35f68701e05d7efd602e2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ legacy_header_height="18"
+ can_minimize="true"
+ can_resize="false"
+ can_close="true"
+ height="305"
+ layout="topleft"
+ name="simple_outfit_snapshot"
+ single_instance="true"
+ help_topic="snapshot"
+ save_rect="true"
+ save_visibility="false"
+ title="OUTFIT SNAPSHOT"
+ width="351">
+  <ui_ctrl
+   layout="topleft"
+   name="thumbnail_placeholder"
+   top="18"
+   left="22"
+   width="335"
+   height="200"
+   follows="top|left"/>
+  <button
+   follows="left|bottom"
+   height="22"
+   layout="topleft"
+   left="29"
+   label="Take photo"
+   name="new_snapshot_btn"
+   bottom="-15"
+   width="90" />
+  <button
+   follows="left|bottom"
+   height="22"
+   layout="topleft"
+   left_pad="10"
+   label="Save (L$[UPLOAD_COST])"
+   name="save_btn"
+   width="90" />
+  <button
+   follows="left|bottom"
+   height="22"
+   layout="topleft"
+   left_pad="10"
+   label="Cancel"
+   name="cancel_btn"
+   width="90" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index 582774895f38a06c3bf9be41b23f696c0ad2e2a7..2064ca811381397907e29b7131552d6e847e452b 100644
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -76,7 +76,7 @@
      word_wrap="true"
      text_readonly_color="LabelDisabledColor"
      width="552">
-      I have read and agree to the [CURRENT_GRID] Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements.
+      I consent to the Linden Lab Terms of Service, Second Life Terms and Conditions, and acknowledge receipt of the Privacy Policy.
     </text>
     <button
      enabled="false"
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 842184de883cea353f714d0ebc0f86c4eee72980..bab37c625898f459b966d12280f6a4a96c17ee78 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -8,16 +8,6 @@
  tab_stop="false" 
  name="main_view"
  width="1024">
-
-  <!-- At the moment layout_stack is not an LLUICtrl,
-  but Tab requires focus_root to function and focus_root
-  functionality is implemented in LLUICtrl -->
-  <panel follows="all"
-         height="768"
-         name="menu_tab_wrapper"
-         mouse_opaque="false"
-         focus_root="true"
-         top="0">
   <layout_stack border_size="0"
                 follows="all"
                 mouse_opaque="false"
@@ -25,31 +15,35 @@
                 name="menu_stack"
                 orientation="vertical"
                 top="0">
+    <!-- Menu, nav bar and status bar need common focus_root-->
     <layout_panel mouse_opaque="true"
               follows="left|right|top"
               name="status_bar_container"
+              focus_root="true"
               height="19"
               left="0"
               top="0"
               width="1024"
               auto_resize="false"
-              default_tab_group="1"
               visible="true">
       <view mouse_opaque="false"
-            follows="all"
+            follows="top|left|right"
             name="menu_bar_holder"
+            tab_group="1"
             left="0"
             top="0"
             width="1024"
-            tab_group="1"
             height="19"/>
+      <view mouse_opaque="false"
+            follows="top|left|right"
+            name="nav_bar_container"
+            tab_group="3"
+            left="0"
+            top="19"
+            width="1024"
+            height="34"
+            visible="false"/>
     </layout_panel>
-    <layout_panel auto_resize="false"
-                  height="34"
-                  mouse_opaque="false"
-                  name="nav_bar_container"
-                  width="1024"
-                  visible="false"/>
     <layout_panel auto_resize="true"  
                   follows="all"
                   height="500"
@@ -109,7 +103,6 @@
              tab_stop="false"/>
     </layout_panel>
   </layout_stack>
-  </panel> <!--menu_tab_wrapper-->
  
   <panel top="0"
         follows="all"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 12f5dddceefd97d9758c559514ee94e649e4aa58..271e219800f6e842a850629e6ac42975a930021f 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -9865,7 +9865,7 @@ Do you wish to continue?
     The selected object affects the navmesh.  Changing it to a Flexible Path will remove it from the navmesh.
     <tag>confirm</tag>
     <usetemplate
-     ignoretext="The selected object affects the navmesh.  Changing it to a Flexible Path will remove it from the navmesh."
+     ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh."
      name="okcancelignore"
      notext="Cancel"
      yestext="OK"/>
@@ -12124,6 +12124,22 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
       yestext="OK"/>
   </notification>
 
+  <notification
+    icon="alertmodal.tga"
+    name="RiggedMeshAttachedToHUD"
+    type="alertmodal">
+    An object "[NAME]" attached to HUD point "[POINT]" contains rigged mesh.
+
+Rigged mesh objects are designed for attachment to the avatar. You will see this object but no one else will.
+
+If you want others to see this object, remove it and re-attach it to an avatar attachment point.
+    <tag>confirm</tag>
+    <usetemplate
+        ignoretext="Warn me when rigged mesh is attached to HUD point."
+        name="okignore"
+        yestext="OK"/>
+  </notification>
+
   <!-- ALCHEMY BELOW THIS LINE -->
     <notification
    icon="notifytip.tga"
@@ -12697,5 +12713,4 @@ Would you like to reset the graphic preferences?
   notext="Leave as-is"
   canceltext="Never reset"/>
  </notification>
-
 </notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
index 4de56b424e15b1a5d411c5477e7ff5aad9a7325a..edc1fb21e79602078e8d53e6681d04f8c58c2ea4 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -17,26 +17,6 @@
    top="5"
    orientation="vertical"
    width="242">
-    <layout_panel
-     auto_resize="false"
-     height="26"
-     layout="topleft"
-     left_delta="0"
-     name="translate_chat_checkbox_lp"
-     top_delta="0"
-     visible="true"
-     width="230">
-      <check_box
-       top="10"
-       control_name="TranslateChat"
-       enabled="true"
-       height="16"
-       label="Translate chat"
-       layout="topleft"
-       left="5"
-       name="translate_chat_checkbox"
-       width="230" />
-    </layout_panel>
     <layout_panel
      auto_resize="true"
      height="138"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 28bb6d33b81101cebf0c31e65058a265db1c5227..6fdb2bdd6b1b5ee3f77628b08f8a91f9566d8f8f 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -322,165 +322,172 @@
 		name="enable_voice_check"
 		width="110"/>
 	<!-- -->
-    <text
-        follows="left|top"
-        layout="topleft"
-        height="15"
-        left="0"
-        top_pad="3"
-        width="120"
-        halign="right"
-        name="media_autoplay_label">
-         Media auto-play
-    </text>
-    <combo_box
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   layout="topleft"
+   left="23"
+   top_delta="22"
+   name="Listen media from"
+   height="15"
+   word_wrap="true"
+   width="112">
+      Hear media and sounds from:
+  </text>
+  <radio_group
+   control_name="MediaSoundsEarLocation"
+   follows="left|top"
+   top_delta="-6"
+   layout="topleft"
+   left_pad="20"
+   width="360"
+   height="40"
+   name="media_ear_location">
+      <radio_item
+       height="19"
+       label="Camera position"
+       follows="left|top"
+       layout="topleft"
+       name="0"
+       width="200"/>
+      <radio_item
+       height="19"
+       follows="left|top"
+       label="Avatar position"
+       layout="topleft"
+       left_delta="0"
+       name="1"
+       top_delta ="18"
+       width="200" />
+  </radio_group>  
+ 	<check_box
+    name="media_show_on_others_btn"
+    control_name="MediaShowOnOthers"
+    value="true"
+    follows="left|top"
+    layout="topleft" 
+    height="15"
+    top_pad="8"
+    tool_tip="Uncheck this to hide media attached to other avatars nearby"
+    label="Play media attached to other avatars"
+    left="20"
+    width="230"/>
+  <text
+   follows="left|top"
+   layout="topleft"
+   height="15"
+   left="23"
+   top_pad="8"
+   width="120"
+   name="media_autoplay_label">
+    Auto-play media
+  </text>
+  <combo_box
         control_name="ParcelMediaAutoPlayEnable"
         enabled_control="AudioStreamingMedia"
         follows="left|top"
         layout="topleft"
         height="23"
-        left_pad="7"
+        left_pad="-15"
         top_delta="-4"
         name="media_auto_play_combo"
-        width="100">
-      <item
-          label="No"
-          name="autoplay_disabled"
-          value="0"/>      
-      <item
-          label="Yes"
-          name="autoplay_enabled"
-          value="1"/>
-      <item
-          label="Ask"
-          name="autoplay_ask"
-          value="2"/>
-    </combo_box>
- 	<check_box
-		name="media_show_on_others_btn"
-		control_name="MediaShowOnOthers"
-		value="true"
-		follows="left|bottom|right"
-		height="15"
-		tool_tip="Uncheck this to hide media attached to other avatars nearby"
-		label="Play media attached to other avatars"
-		left="25"
-    width="230"/>
-	<check_box
-		name="gesture_audio_play_btn"
-		control_name="EnableGestureSounds"
-        disabled_control="MuteAudio"
-		value="true"
-		follows="left|bottom|right"
-		height="15"
-		tool_tip="Check this to hear sounds from gestures"
-		label="Play sounds from gestures"
-		top_pad="1"
-		left="25"/>
-	<check_box
-		name="sound_on_collisions"
-		control_name="EnableCollisionSounds"
-        disabled_control="MuteAudio"
-		value="true"
-		follows="left|bottom|right"
-		height="15"
-		tool_tip="Check this to hear sounds from collisions with objects and avatars"
-		label="Play sounds from collisions"
-		top_pad="1"
-		left="25"/>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="20"
-     layout="topleft"
-     left="25"
-     name="voice_chat_settings"
-     width="200"
-     top_pad="16">
-	  Voice Chat Settings
-    </text>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     layout="topleft"
-	   left="46"
-	   top_delta="16"
-     name="Listen from"
-     width="112">
-        Listen from:
-    </text>
-	<icon
-		follows="left|top"
-		height="18"
-		image_name="Cam_FreeCam_Off"
-		layout="topleft"
-		name="camera_icon"
-		mouse_opaque="false"
-		visible="true"
-		width="18"
-		left_pad="-4"
-		top_delta="-5"/>
-	<icon
-		follows="left|top"
-		height="18"
-		image_name="Move_Walk_Off"
-		layout="topleft"
-		left_pad="170" 
-		name="avatar_icon"
-		mouse_opaque="false"
-		visible="true"
-		width="18"
-		top_delta="0" />
-   <radio_group
-     enabled_control="EnableVoiceChat"
-     control_name="VoiceEarLocation"
-     follows="left|top"
-     layout="topleft"
-     left_delta="-168"
-     width="360"
-     height="20"
-     name="ear_location">
-    <radio_item
-     height="19"
-     label="Camera position"
-     follows="left|top"
-     layout="topleft"
-     name="0"
-     width="200"/>
-    <radio_item
-     height="19"
-     follows="left|top"
-     label="Avatar position"
-     layout="topleft"
-     left_pad="-16"
-     name="1"
-     top_delta ="0" 
-     width="200" />
-   </radio_group>
+        width="115">
+    <item
+        label="Never"
+        name="autoplay_disabled"
+        value="0"/>
+    <item
+        label="Always"
+        name="autoplay_enabled"
+        value="1"/>
+    <item
+        label="Ask"
+        name="autoplay_ask"
+        value="2"/>
+  </combo_box>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   layout="topleft"
+   left="23"
+   top_delta="30"
+   name="Listen from"
+   width="112">
+     Hear voice from:
+  </text>
+  <radio_group
+   enabled_control="EnableVoiceChat"
+   control_name="VoiceEarLocation"
+   follows="left|top"
+   layout="topleft"
+   left_pad="20"
+   top_delta="-6"
+   width="360"
+   height="40"
+   name="ear_location">
+   <radio_item
+    height="19"
+    label="Camera position"
+    follows="left|top"
+    layout="topleft"
+    name="0"
+    width="200"/>
+   <radio_item
+    height="19"
+    follows="left|top"
+    label="Avatar position"
+    layout="topleft"
+    left_delta="0"
+    name="1"
+    top_delta ="18" 
+    width="200" />
+  </radio_group>
   <check_box
    control_name="LipSyncEnabled"
    follows="left|top"
    height="15"
    label="Move avatar lips when speaking"
    layout="topleft"
-   left="44"
+   left="20"
    name="enable_lip_sync"
-   top_pad="5" 
+   top_pad="10" 
    width="237"/>
- <check_box
-  follows="top|left"
-  enabled_control="EnableVoiceChat"
-  control_name="PushToTalkToggle"
-  height="15"
-  label="Toggle speak on/off when I press button in toolbar"
-  layout="topleft"
-  left="44"
-  name="push_to_talk_toggle_check"
-  width="237"
-  tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
-  top_pad="3"/>
+  <check_box
+   follows="top|left"
+   enabled_control="EnableVoiceChat"
+   control_name="PushToTalkToggle"
+   height="15"
+   label="Toggle speak on/off when I press button in toolbar"
+   layout="topleft"
+   left="20"
+   name="push_to_talk_toggle_check"
+   width="237"
+   tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
+   top_pad="5"/>
+  <check_box
+   name="gesture_audio_play_btn"
+   control_name="EnableGestureSounds"
+   disabled_control="MuteAudio"
+   value="true"
+   follows="left|bottom|right"
+   height="15"
+   tool_tip="Check this to hear sounds from gestures"
+   label="Play sounds from gestures"
+   top_pad="5"
+   left="20"/>
+  <check_box
+   name="sound_on_collisions"
+   control_name="EnableCollisionSounds"
+   disabled_control="MuteAudio"
+   value="true"
+   follows="left|bottom|right"
+   height="15"
+   tool_tip="Check this to hear sounds from collisions with objects and avatars"
+   label="Play sounds from collisions"
+   top_pad="5"
+   left="20"/>
   <button
    control_name="ShowDeviceSettings"
    follows="left|top"
@@ -489,7 +496,7 @@
    label="Voice Input/Output devices"
    layout="topleft"
    left="20"
-   top_pad="6"
+   top_pad="9"
    name="device_settings_btn"
    width="230">
   </button>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 3229a9dcd1fe5457c77d86df9bc1aefcd0944e48..7d21606fbf05bd74e3727b469947688d3e5a1bb3 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4352,6 +4352,10 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>
   <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">
       The physics shape contains bad confirmation data. Try to correct the physics model.
   </string>
+  <!-- MAV_BLOCK_MISSING means server didn't get and couldn't substitute physics_convex, high_lod or BoundingVerts-->
+  <string name="Mav_Details_MAV_BLOCK_MISSING">
+    Missing data. Make sure high lod is present and valid. Set the physics model if not set.
+  </string>
   <string name="Mav_Details_MAV_UNKNOWN_VERSION">
       The physics shape does not have correct version. Set the correct version for the physics model.
   </string>