diff --git a/.hgtags b/.hgtags
index c892fcb28e800f4ad46772dbc8cd2acc9b7a12b1..2f8b18b18819ef503800b1d5939a0c42ce2d7547 100755
--- a/.hgtags
+++ b/.hgtags
@@ -56,11 +56,11 @@ a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
+b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
-b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
 63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
 4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
 4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
@@ -248,33 +248,31 @@ bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156
 6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
 2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
 24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
-a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
-9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
 5910f8063a7e1ddddf504c2f35ca831cc5e8f469 DRTVWR-160
 f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 3.3.3-beta1
 f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 DRTVWR-144
-089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
-600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
-c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
 2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
+600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
 80b5e5e9775966d3839331ffa7a16a60f9d7c930 DRTVWR-165
 fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
 af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
 4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
 6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
+a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
+9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
+089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
+c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
 b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
 050e48759337249130f684b4a21080b683f61732 DRTVWR-168
 09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
 f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
 f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1
-005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
 bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173
 cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174
 82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2
 57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176
 eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177
 a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
-888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
 4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180
 5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183
 6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4
@@ -285,32 +283,24 @@ ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
 7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
 8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
 351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
+005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
+888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
 a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
 1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1
-81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
-47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190
-cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
-c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
 9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
+47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190
 421126293dcbde918e0da027ca0ab9deb5b4fbf2 DRTVWR-192
-4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
 33a2fc7a910ae29ff8b4850316ed7fbff9f64d33 DRTVWR-195
 e9732c739c8a72a590216951505ea9c76a526a84 DRTVWR-193
-78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
 7602f61c804a512764e349c034c02ddabeefebc4 DRTVWR-196
 ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198
 507bdfbd6bf844a511c1ffeda4baa80016ed1346 DRTVWR-197
 b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
 37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
 182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
-248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
 7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
 84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
-de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
 573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
-34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
-6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
-7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
 af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
 015012c2b740ccdec8a8c3d6e5f898449ecfe0b8 DRTVWR-213
 62b07aa81b1957897c3846292bb9412977b0af6c 3.3.4-beta6
@@ -319,7 +309,6 @@ ceed0b65a69f1eac20d523e0203320a32f9a3f3c DRTVWR-215
 97977c67245f52db20eb15f1918cc0f24778cabc 3.4.0-release
 5adb2b8f96c3cac88ad7c7d996d707f1b29df336 3.4.1-beta1
 b3f74858a1c8720c82d0978f3877a3fc8ba459ec 3.4.1-beta1a
-b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
 2b779f233ee6f38c89cb921650c773a96e63da92 DRTVWR-220
 0b9d95f4bfb6867cbf56eaec51633b0da2f1262d DRTVWR-221
 e6e553761829dc0270eaaa712b7cb0622535b076 3.4.1-beta3
@@ -344,31 +333,36 @@ baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236
 b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237
 3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12
 e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release
+81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
+cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
+c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
+4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
+78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
+248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
+de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
+34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
+6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
+7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
+b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
 32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
 704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1
-d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
-e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
 288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216
 e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
-93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
 0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
 710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
-2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209
-f7bedce18ad52283e6072814db23318907261487 DRTVWR-238
-7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210
 e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
 73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
 16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
+d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
+e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
+93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
+2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209
+f7bedce18ad52283e6072814db23318907261487 DRTVWR-238
+7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210
 5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
 f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
 4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
 94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1
-4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
-f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
-39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
-7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
-f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
-b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
 965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252
 bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251
 ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
@@ -377,25 +371,31 @@ ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
 44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258
 c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257
 452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259
-9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
 daca610d840625b5bebb966a57cb49581852c417 DRTVWR-265
 9afbdc4e24cc04feacfb2b7a10b78a64f780901a DRTVWR-266
 73280db02501f5ad041fc18b1eba68e73a81996c DRTVWR-267
 870e2d79e0063fda87187f17bbc2747766733194 3.4.3-beta3
 0a2ca6546b499239afeb66d17b2fadbcdbe36ab1 3.4.3-release
+4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
+f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
+39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
+7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
+f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
+b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
+9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
 84fbaf2d4141bd161731430e760949dc787ca206 DRTVWR-244
 083d2d36b5bb1c54fc3dd7caac0e7ac381a9cef0 3.4.4-beta1
-391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
 b634dec987c16e8c9c938e11e52591d9ead8fa9b DRTVWR-270
 cd39255bd23330fd30c04105f2811e941d8524fe 3.4.4-beta2
 2c4011bbc2b15b82198fd8b51f3a9fe765a08c4d DRTVWR-271
 2f8a3ef687bc55828abcb17ac1ad7cde70536d7e 3.4.4-beta3
 35cfd4cf5b895fa776592f2e630e330be7f0604e DRTVWR-273
-a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
-37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
 c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275
 05d9f1dd7a954069af2a33abedb7713fa36a04cb 3.4.4-beta4
 e1bb1ae7d8b12faeb37933a737c199cc9b9f89cc 3.4.4-release
+391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
+a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
+37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
 7c6dfdc1b7a2ce0d8e3a8f3ce3058547ea065c0f DRTVWR-250
 b9ff9730daa53a541925300cbd02bb14575a5705 DRTVWR-277
 af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276
@@ -405,8 +405,6 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280
 5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281
 7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283
 6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2
-37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282
-6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284
 ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286
 2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287
 e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3
@@ -460,9 +458,9 @@ a314f1c94374ab1f6633dd2983f7090a68663eb2 3.5.2-beta4
 9b1b6f33aa5394b27bb652b31b5cb81ef6060370 3.5.2-release
 a277b841729f2a62ba1e34acacc964bc13c1ad6f 3.5.3-release
 fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1
-69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
-69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
 0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release
 75cf8e855ae1af6895a35da475314c2b5acf1850 3.6.1-release
 f6741d5fe8d632651424484df0fe0cb4a01e9fbe 3.6.2-release
 fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
+83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
+91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
diff --git a/BuildParams b/BuildParams
index 84d30f651bad54782baf50b8fb0f3dcb4e8c4900..327530934d288942111ea437cda3ef7acb3c05d5 100755
--- a/BuildParams
+++ b/BuildParams
@@ -26,6 +26,9 @@ codeticket_since = 3.3.0-release
 Linux.gcc_version = /usr/bin/gcc-4.6
 Linux.cxx_version = /usr/bin/g++-4.6
 
+# Setup default sourceid so Windows can pick up the TeamCity override
+sourceid = ""
+
 ################################################################
 ####      Examples of how to set the viewer_channel         ####
 #
@@ -131,17 +134,6 @@ viewer-materials.build_debug_release_separately = true
 viewer-materials.build_CYGWIN_Debug = false
 viewer-materials.build_viewer_update_version_manager = false
 
-# viewer-chui
-#
-# ========================================
-
-viewer-chui.viewer_channel = "Project Viewer - CHUI"
-viewer-chui.login_channel = "Project Viewer - CHUI"
-viewer-chui.viewer_grid = agni
-viewer-chui.build_debug_release_separately = true
-viewer-chui.build_CYGWIN_Debug = false
-viewer-chui.build_viewer_update_version_manager = false
-
 # =================================================================
 # asset delivery 2010 projects
 # =================================================================
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 6c5b55795dc40c0ce019b5b712315fb05dd277db..e0bacc3a01acafa3218ebf862a271968eb5913ca 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -176,7 +176,10 @@ Ansariel Hiller
 	STORM-1713
 	STORM-1899
 	MAINT-2368
+	STORM-1931
 Aralara Rajal
+Arare Chantilly
+	CHUIBUG-191
 Ardy Lay
 	STORM-859
 	VWR-19499
diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index b9ec8f5266beb054d97c26544b03c294b6ffcfde..af2063ce6d7ad8d2f9d241baec448ec41734df0e 100755
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -18,7 +18,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
            find_program(MERCURIAL hg)
            if (DEFINED MERCURIAL)
               execute_process(
-                 COMMAND ${MERCURIAL} log -r tip --template "{p1rev}"
+                 COMMAND ${MERCURIAL} log -r tip --template "{rev}"
                  OUTPUT_VARIABLE VIEWER_VERSION_REVISION
                  OUTPUT_STRIP_TRAILING_WHITESPACE
                  )
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index e003ed77883684fd8f54604332e49d048c263048..774e8c0676e21f5276cbecab33f582a2b1f4d0f3 100755
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -3,3 +3,4 @@ Wed Nov  7 00:25:19 UTC 2012
 
 
 
+
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 9cb830a2dbd1956424cbfb3063f2f6dfcf569ef2..54049b5545bf8ef9dae8321b5ded922b7240228a 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -392,11 +392,21 @@ class LLManifest(object):
             raise ManifestError, "Should be something at path " + path
         self.created_paths.append(path)
 
-    def put_in_file(self, contents, dst):
+    def put_in_file(self, contents, dst, src=None):
         # write contents as dst
-        f = open(self.dst_path_of(dst), "wb")
-        f.write(contents)
-        f.close()
+        dst_path = self.dst_path_of(dst)
+        f = open(dst_path, "wb")
+        try:
+            f.write(contents)
+        finally:
+            f.close()
+
+        # Why would we create a file in the destination tree if not to include
+        # it in the installer? The default src=None (plus the fact that the
+        # src param is last) is to preserve backwards compatibility.
+        if src:
+            self.file_list.append([src, dst_path])
+        return dst_path
 
     def replace_in(self, src, dst=None, searchdict={}):
         if dst == None:
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index f188865eb004b7395928773dc715461a31aa862a..3e68ef068e5061d2905ee61a04a58d525f965e3d 100755
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -608,9 +608,6 @@ namespace tut
     void object::test<5>()
     {
         set_test_name("exit(2)");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
         PythonProcessLauncher py(get_test_name(),
                                  "import sys\n"
                                  "sys.exit(2)\n");
@@ -622,10 +619,7 @@ namespace tut
     template<> template<>
     void object::test<6>()
     {
-        set_test_name("syntax_error:");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
+        set_test_name("syntax_error");
         PythonProcessLauncher py(get_test_name(),
                                  "syntax_error:\n");
         py.mParams.files.add(LLProcess::FileParam()); // inherit stdin
@@ -647,9 +641,6 @@ namespace tut
     void object::test<7>()
     {
         set_test_name("explicit kill()");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
         PythonProcessLauncher py(get_test_name(),
                                  "from __future__ import with_statement\n"
                                  "import sys, time\n"
@@ -694,9 +685,6 @@ namespace tut
     void object::test<8>()
     {
         set_test_name("implicit kill()");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
         NamedTempFile out("out", "not started");
         LLProcess::handle phandle(0);
         {
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index a8149a9a1dae6372f63f1d644ae28d8554e318f7..44f2c1efe92d98a586b437efea382ad802fa0406 100755
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -644,7 +644,7 @@ void LLButton::draw()
     //  Cancel sticking of color, if the button is pressed,
 	//  or when a flashing of the previously selected button is ended
 	if (mFlashingTimer
-		&& ((selected && !mFlashingTimer->isFlashingInProgress()) || pressed))
+		&& ((selected && !mFlashingTimer->isFlashingInProgress() && !mForceFlashing) || pressed))
 	{
 		mFlashing = false;
 	}
@@ -971,8 +971,9 @@ void LLButton::setToggleState(BOOL b)
 	}
 }
 
-void LLButton::setFlashing(bool b)	
+void LLButton::setFlashing(bool b, bool force_flashing/* = false */)
 { 
+	mForceFlashing = force_flashing;
 	if (mFlashingTimer)
 	{
 		mFlashing = b; 
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 060db59a8a6e088eb1661357961a7f4bf4317871..7b4719866d55b3a1c2bc3f0a7145f0cd95b1558c 100755
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -201,7 +201,7 @@ public:
 	void			setToggleState(BOOL b);
 
 	void			setHighlight(bool b);
-	void			setFlashing( bool b );
+	void			setFlashing( bool b, bool force_flashing = false );
 	BOOL			getFlashing() const		{ return mFlashing; }
     LLFlashTimer*   getFlashTimer() {return mFlashingTimer;}
 
@@ -378,7 +378,7 @@ protected:
 
 	LLFrameTimer				mFrameTimer;
 	LLFlashTimer *				mFlashingTimer;
-
+	bool                        mForceFlashing; // Stick flashing color even if button is pressed
 	bool						mHandleRightMouse;
 };
 
diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 6a1b48a08a3d4b52754fdeb6158569ab54b18e82..c04b70eb649340610399b84ad788b852099ef863 100755
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -62,9 +62,9 @@ void LLChatEntry::draw()
 {
 	if(mIsExpandable)
 	{
+		reflow();
 		expandText();
 	}
-
 	LLTextEditor::draw();
 }
 
@@ -158,19 +158,21 @@ void LLChatEntry::onValueChange(S32 start, S32 end)
     resetLabel();
 }
 
-bool LLChatEntry::useLabel()
+bool LLChatEntry::useLabel() const
 {
     return !getLength() && !mLabel.empty();
 }
 
 void LLChatEntry::onFocusReceived()
 {
-
+	LLUICtrl::onFocusReceived();
+	updateAllowingLanguageInput();
 }
 
 void LLChatEntry::onFocusLost()
 {
-
+	LLTextEditor::focusLostHelper();
+	LLUICtrl::onFocusLost();
 }
 
 BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
index 49c8d21450c9fa05d81c632f1ab79147a161d711..e67f39b21b610bcbdca067558c2dae6be1b6ab19 100755
--- a/indra/llui/llchatentry.h
+++ b/indra/llui/llchatentry.h
@@ -56,14 +56,14 @@ protected:
 	LLChatEntry(const Params& p);
     /*virtual*/ void    beforeValueChange();
     /*virtual*/ void    onValueChange(S32 start, S32 end);
-    /*virtual*/ bool    useLabel();
+    /*virtual*/ bool    useLabel() const;
 
 public:
 
 	virtual void	draw();
 	virtual	void	onCommit();
-    /*virtual*/ void	onFocusReceived();
-    /*virtual*/ void	onFocusLost();
+	/*virtual*/ void	onFocusReceived();
+	/*virtual*/ void	onFocusLost();
 
 	void enableSingleLineMode(bool single_line_mode);
 	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 09e27a264aa151399208526cf86d02ee21d7ba2d..273ceb40386117dcdf505bdc9161f4961d712b1c 100755
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -507,22 +507,11 @@ LLFloater::~LLFloater()
 {
 	LLFloaterReg::removeInstance(mInstanceName, mKey);
 	
-//	delete mNotificationContext;
-//	mNotificationContext = NULL;
-
-	//// am I not hosted by another floater?
-	//if (mHostHandle.isDead())
-	//{
-	//	LLFloaterView* parent = (LLFloaterView*) getParent();
-
-	//	if( parent )
-	//	{
-	//		parent->removeChild( this );
-	//	}
-	//}
-
-	// Just in case we might still have focus here, release it.
-	releaseFocus();
+	if( gFocusMgr.childHasKeyboardFocus(this))
+	{
+		// Just in case we might still have focus here, release it.
+		releaseFocus();
+	}
 
 	// This is important so that floaters with persistent rects (i.e., those
 	// created with rect control rather than an LLRect) are restored in their
@@ -1486,6 +1475,7 @@ void LLFloater::moveResizeHandlesToFront()
 	}
 }
 
+/*virtual*/
 BOOL LLFloater::isFrontmost()
 {
 	LLFloaterView* floater_view = getParentByType<LLFloaterView>();
@@ -1504,7 +1494,7 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition)
 		floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp));
 		floaterp->setSnapTarget(getHandle());
 	}
-	gFloaterView->adjustToFitScreen(floaterp, FALSE);
+	gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE);
 	if (floaterp->isFrontmost())
 	{
 		// make sure to bring self and sibling floaters to front
@@ -2735,7 +2725,7 @@ void LLFloaterView::refresh()
 
 const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
 
-void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside)
+void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars/* = false*/)
 {
 	if (floater->getParent() != this)
 	{
@@ -2788,7 +2778,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
 	}
 
 	// move window fully onscreen
-	if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
+	if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
 	{
 		floater->clearSnapTarget();
 	}
@@ -3258,6 +3248,11 @@ bool LLFloater::isShown() const
     return ! isMinimized() && isInVisibleChain();
 }
 
+bool LLFloater::isDetachedAndNotMinimized()
+{
+	return !getHost() && !isMinimized();
+}
+
 /* static */
 bool LLFloater::isShown(const LLFloater* floater)
 {
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 4dba1e645f5bdcf3d6319180c24efa89879c8170..3482314698ea282b65463fb7222e383e9e9d341f 100755
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -238,6 +238,7 @@ public:
 	void			center();
 
 	LLMultiFloater* getHost();
+	bool isDetachedAndNotMinimized();
 
 	void			applyTitle();
 	std::string		getCurrentTitle() const;
@@ -261,7 +262,7 @@ public:
 	static bool     isVisible(const LLFloater* floater);
 	static bool     isMinimized(const LLFloater* floater);
 	BOOL			isFirstLook() { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts
-	BOOL			isFrontmost();
+	virtual BOOL	isFrontmost();
 	BOOL			isDependent()					{ return !mDependeeHandle.isDead(); }
 	void			setCanMinimize(BOOL can_minimize);
 	void			setCanClose(BOOL can_close);
@@ -528,7 +529,7 @@ public:
 	LLRect			findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor );
 
 	// Given a child of gFloaterView, make sure this view can fit entirely onscreen.
-	void			adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside);
+	void			adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars = false);
 
 	void			setMinimizePositionVerticalOffset(S32 offset) { mMinimizePositionVOffset = offset; }
 	void			getMinimizePosition( S32 *left, S32 *bottom);
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 1cdddf0d5b93e830eabc4776cabcfb26bf3dd6e0..b1b75776a7b43bc56a4dca5d419103b6faced0cb 100755
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -356,8 +356,8 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)
 {
 	std::string controlname = getRectControlName(name);
 	LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
-												 llformat("Window Size for %s", name.c_str()),
-												 TRUE);
+											  llformat("Window Size for %s", name.c_str()),
+											  LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 }
 
@@ -367,7 +367,7 @@ std::string LLFloaterReg::declarePosXControl(const std::string& name)
 	LLFloater::getControlGroup()->declareF32(controlname, 
 											10.f,
 											llformat("Window X Position for %s", name.c_str()),
-											TRUE);
+											LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 }
 
@@ -377,7 +377,7 @@ std::string LLFloaterReg::declarePosYControl(const std::string& name)
 	LLFloater::getControlGroup()->declareF32(controlname,
 											10.f,
 											llformat("Window Y Position for %s", name.c_str()),
-											TRUE);
+											LLControlVariable::PERSIST_NONDFT);
 
 	return controlname;
 }
@@ -404,7 +404,7 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
 	std::string controlname = getVisibilityControlName(name);
 	LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,
 												 llformat("Window Visibility for %s", name.c_str()),
-												 TRUE);
+												 LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 }
 
@@ -414,7 +414,7 @@ std::string LLFloaterReg::declareDockStateControl(const std::string& name)
 	std::string controlname = getDockStateControlName(name);
 	LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,
 												 llformat("Window Docking state for %s", name.c_str()),
-												 TRUE);
+												 LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 
 }
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 8aa1eb7cd59b68196cd660c169914ce8b3f30a47..cf449217f5756dc33802e6a0376453d342cbc17f 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -323,9 +323,11 @@ static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
 
 void LLFolderView::filter( LLFolderViewFilter& filter )
 {
+    // Entry point of inventory filtering (CHUI-849)
 	LLFastTimer t2(FTM_FILTER);
-	filter.setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+    filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
 
+    // Note: we filter the model, not the view
 	getViewModelItem()->filter(filter);
 }
 
@@ -661,7 +663,7 @@ void LLFolderView::draw()
 
 		// get preferable text height...
 		S32 pixel_height = mStatusTextBox->getTextPixelHeight();
-		bool height_changed = local_rect.getHeight() != pixel_height;
+		bool height_changed = (local_rect.getHeight() < pixel_height);
 		if (height_changed)
 		{
 			// ... if it does not match current height, lets rearrange current view.
@@ -1601,15 +1603,17 @@ void LLFolderView::update()
 	{
 		mNeedsAutoSelect = TRUE;
 	}
-	// filter to determine visibility before arranging
+    
+	// Filter to determine visibility before arranging
 	filter(getFolderViewModel()->getFilter());
-	// Clear the modified setting on the filter only if the filter count is non-zero after running the filter process
-	// Note: if the filter count is zero, then the filter most likely halted before completing the entire set of items
-	if (getFolderViewModel()->getFilter().isModified() && (getFolderViewModel()->getFilter().getFilterCount() > 0))
+    
+	// Clear the modified setting on the filter only if the filter finished after running the filter process
+	// Note: if the filter count has timed out, that means the filter halted before completing the entire set of items
+    if (getFolderViewModel()->getFilter().isModified() && (!getFolderViewModel()->getFilter().isTimedOut()))
 	{
 		getFolderViewModel()->getFilter().clearModified();
 	}
-
+    
 	// automatically show matching items, and select first one if we had a selection
 	if (mNeedsAutoSelect)
 	{
@@ -1649,11 +1653,13 @@ void LLFolderView::update()
 
   BOOL is_visible = isInVisibleChain();
 
-  //Puts folders/items in proper positions
-  if ( is_visible )
+  // Puts folders/items in proper positions
+  // arrange() takes the model filter flag into account and call sort() if necessary (CHUI-849)
+  // It also handles the open/close folder animation
+  if (is_visible)
   {
     sanitizeSelection();
-    if( needsArrange() )
+    if (needsArrange())
     {
       S32 height = 0;
       S32 width = 0;
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index fdb4108afbf48e485d37e994312419c02f7289b2..6c147ccc12eee6e15469be6b6b0816b377f9a07b 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -274,6 +274,7 @@ void LLFolderViewItem::refresh()
 	}
 
 	mLabelWidthDirty = true;
+    // Dirty the filter flag of the model from the view (CHUI-849)
 	vmi.dirtyFilter();
 }
 
@@ -943,11 +944,17 @@ void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
 
 static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
 
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
+// Make everything right and in the right place ready for drawing (CHUI-849)
+// * Sort everything correctly if necessary
+// * Turn widgets visible/invisible according to their model filtering state
+// * Takes animation state into account for opening/closing of folders (this makes widgets visible/invisible)
+// * Reposition visible widgets so that they line up correctly with no gap
+// * Compute the width and height of the current folder and its children
+// * Makes sure that this view and its children are the right size
 S32 LLFolderViewFolder::arrange( S32* width, S32* height )
 {
-	// sort before laying out contents
+	// Sort before laying out contents
+    // Note that we sort from the root (CHUI-849)
 	getRoot()->getFolderViewModel()->sort(this);
 
 	LLFastTimer t2(FTM_ARRANGE);
@@ -1613,16 +1620,13 @@ void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 }
 
 void LLFolderViewFolder::requestArrange()
-{ 
-	if ( mLastArrangeGeneration != -1)
-	{
-		mLastArrangeGeneration = -1; 
-		// flag all items up to root
-		if (mParentFolder)
-		{
-			mParentFolder->requestArrange();
-		}
-	}
+{
+    mLastArrangeGeneration = -1;
+    // flag all items up to root
+    if (mParentFolder)
+    {
+        mParentFolder->requestArrange();
+    }
 }
 
 void LLFolderViewFolder::toggleOpen()
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index ca31931e19443d94400473c4c1189fcc50217c71..a9b0201236b9ff3174695a0dabb8424d015f3a1b 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -316,7 +316,6 @@ protected:
 	F32			mAutoOpenCountdown;
 	S32			mLastArrangeGeneration;
 	S32			mLastCalculatedWidth;
-	S32			mMostFilteredDescendantGeneration;
 	bool		mNeedsSort;
 
 public:
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index 3593804554aa722b08ed9943423b059b19a6f7a4..3363dc531652b54c66fb332efea086d20f928450 100755
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -48,7 +48,7 @@ std::string LLFolderViewModelCommon::getStatusText()
 
 void LLFolderViewModelCommon::filter()
 {
-	getFilter().setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+    getFilter().resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
 	mFolderView->getViewModelItem()->filter(getFilter());
 }
 
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 1b61212c0eadf6e9de74777a52de31e8df456ab2..b1bcc8bbb4912d877b48c7283ddc3c09d55bdb28 100755
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -87,12 +87,11 @@ public:
 	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
 
 	// +-------------------------------------------------------------------+
-	// + Count
+	// + Time
 	// +-------------------------------------------------------------------+
-	virtual void 				setFilterCount(S32 count) = 0;
-	virtual S32 				getFilterCount() const = 0;
-	virtual void 				decrementFilterCount() = 0;
-
+	virtual void 				resetTime(S32 timeout) = 0;
+    virtual bool                isTimedOut() = 0;
+    
 	// +-------------------------------------------------------------------+
 	// + Default
 	// +-------------------------------------------------------------------+
@@ -308,26 +307,28 @@ public:
 	virtual bool potentiallyVisible()
 	{
 		return passedFilter() // we've passed the filter
-			|| getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration() // or we don't know yet
+			|| (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet
 			|| descendantsPassedFilter();
 	}
 
 	virtual bool passedFilter(S32 filter_generation = -1) 
 	{ 
-		if (filter_generation < 0) 
+		if (filter_generation < 0)
+        {
 			filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
-
-		bool passed_folder_filter = mPassedFolderFilter && mLastFolderFilterGeneration >= filter_generation;
-		bool passed_filter = mPassedFilter && mLastFilterGeneration >= filter_generation;
-		return passed_folder_filter
-				&& (descendantsPassedFilter(filter_generation)
-					|| passed_filter);
+        }
+		bool passed_folder_filter = mPassedFolderFilter && (mLastFolderFilterGeneration >= filter_generation);
+		bool passed_filter = mPassedFilter && (mLastFilterGeneration >= filter_generation);
+		return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation));
 	}
 
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1)
 	{ 
-		if (filter_generation < 0) filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
-		return mMostFilteredDescendantGeneration >= filter_generation; 
+		if (filter_generation < 0)
+        {
+            filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
+        }
+		return mMostFilteredDescendantGeneration >= filter_generation;
 	}
 
 
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index e33ac1d5c263bbd4e6d441db4d2a442af83d87c9..c89c0203b4accb5d5e49a4d9ee9dbe8a88379854 100755
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -214,8 +214,15 @@ LLLayoutStack::Params::Params()
 	open_time_constant("open_time_constant", 0.02f),
 	close_time_constant("close_time_constant", 0.03f),
 	resize_bar_overlap("resize_bar_overlap", 1),
-	border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
-{}
+	border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)),
+	show_drag_handle("show_drag_handle", false),
+	drag_handle_first_indent("drag_handle_first_indent", 0),
+	drag_handle_second_indent("drag_handle_second_indent", 0),
+	drag_handle_thickness("drag_handle_thickness", 5),
+	drag_handle_shift("drag_handle_shift", 2)
+{
+	addSynonym(border_size, "drag_handle_gap");
+}
 
 LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p) 
 :	LLView(p),
@@ -227,8 +234,14 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
 	mClip(p.clip),
 	mOpenTimeConstant(p.open_time_constant),
 	mCloseTimeConstant(p.close_time_constant),
-	mResizeBarOverlap(p.resize_bar_overlap)
-{}
+	mResizeBarOverlap(p.resize_bar_overlap),
+	mShowDragHandle(p.show_drag_handle),
+	mDragHandleFirstIndent(p.drag_handle_first_indent),
+	mDragHandleSecondIndent(p.drag_handle_second_indent),
+	mDragHandleThickness(p.drag_handle_thickness),
+	mDragHandleShift(p.drag_handle_shift)
+{
+}
 
 LLLayoutStack::~LLLayoutStack()
 {
@@ -262,6 +275,26 @@ void LLLayoutStack::draw()
 			drawChild(panelp, 0, 0, !clip_rect.isEmpty());
 		}
 	}
+
+	const LLView::child_list_t * child_listp = getChildList();
+	BOOST_FOREACH(LLView * childp, * child_listp)
+	{
+		LLResizeBar * resize_barp = dynamic_cast<LLResizeBar*>(childp);
+		if (resize_barp && resize_barp->isShowDragHandle() && resize_barp->getVisible() && resize_barp->getRect().isValid())
+		{
+			LLRect screen_rect = resize_barp->calcScreenRect();
+			if (LLUI::getRootView()->getLocalRect().overlaps(screen_rect) && LLUI::sDirtyRect.overlaps(screen_rect))
+			{
+				LLUI::pushMatrix();
+				{
+					const LLRect& rb_rect(resize_barp->getRect());
+					LLUI::translate(rb_rect.mLeft, rb_rect.mBottom);
+					resize_barp->draw();
+				}
+				LLUI::popMatrix();
+			}
+		}
+	}
 }
 
 void LLLayoutStack::removeChild(LLView* view)
@@ -390,7 +423,6 @@ void LLLayoutStack::updateLayout()
 	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
 	{
 		F32 panel_dim = llmax(panelp->getExpandedMinDim(), panelp->mTargetDim);
-		F32 panel_visible_dim = panelp->getVisibleDim();
 
 		LLRect panel_rect;
 		if (mOrientation == HORIZONTAL)
@@ -407,27 +439,61 @@ void LLLayoutStack::updateLayout()
 										getRect().getWidth(),
 										llround(panel_dim));
 		}
-		panelp->setIgnoreReshape(true);
-		panelp->setShape(panel_rect);
-		panelp->setIgnoreReshape(false);
 
 		LLRect resize_bar_rect(panel_rect);
-
+		LLResizeBar * resize_barp = panelp->getResizeBar();
+		bool show_drag_handle = resize_barp->isShowDragHandle();
 		F32 panel_spacing = (F32)mPanelSpacing * panelp->getVisibleAmount();
+		F32 panel_visible_dim = panelp->getVisibleDim();
+		S32 panel_spacing_round = (S32)(llround(panel_spacing));
+
 		if (mOrientation == HORIZONTAL)
 		{
-			resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap;
-			resize_bar_rect.mRight = panel_rect.mRight + (S32)(llround(panel_spacing)) + mResizeBarOverlap;
-
 			cur_pos += panel_visible_dim + panel_spacing;
+
+			if (show_drag_handle && panel_spacing_round > mDragHandleThickness)
+			{
+				resize_bar_rect.mLeft = panel_rect.mRight + mDragHandleShift;
+				resize_bar_rect.mRight = resize_bar_rect.mLeft + mDragHandleThickness;
+			}
+			else
+			{
+				resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap;
+				resize_bar_rect.mRight = panel_rect.mRight + panel_spacing_round + mResizeBarOverlap;
+			}
+
+			if (show_drag_handle)
+			{
+				resize_bar_rect.mBottom += mDragHandleSecondIndent;
+				resize_bar_rect.mTop -= mDragHandleFirstIndent;
+			}
+
 		}
 		else //VERTICAL
 		{
-			resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap;
-			resize_bar_rect.mBottom = panel_rect.mBottom - (S32)(llround(panel_spacing)) - mResizeBarOverlap;
-
 			cur_pos -= panel_visible_dim + panel_spacing;
+
+			if (show_drag_handle && panel_spacing_round > mDragHandleThickness)
+			{
+				resize_bar_rect.mTop = panel_rect.mBottom - mDragHandleShift;
+				resize_bar_rect.mBottom = resize_bar_rect.mTop - mDragHandleThickness;
+			}
+			else
+			{
+				resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap;
+				resize_bar_rect.mBottom = panel_rect.mBottom - panel_spacing_round - mResizeBarOverlap;
+			}
+
+			if (show_drag_handle)
+			{
+				resize_bar_rect.mLeft += mDragHandleFirstIndent;
+				resize_bar_rect.mRight -= mDragHandleSecondIndent;
+			}
 		}
+
+		panelp->setIgnoreReshape(true);
+		panelp->setShape(panel_rect);
+		panelp->setIgnoreReshape(false);
 		panelp->mResizeBar->setShape(resize_bar_rect);
 	}
 
@@ -475,14 +541,13 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)
 	{
 		if (lp->mResizeBar == NULL)
 		{
-			LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
-
 			LLResizeBar::Params resize_params;
 			resize_params.name("resize");
 			resize_params.resizing_view(lp);
 			resize_params.min_size(lp->getRelevantMinDim());
-			resize_params.side(side);
+			resize_params.side((mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM);
 			resize_params.snapping_enabled(false);
+			resize_params.show_drag_handle(mShowDragHandle);
 			LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params);
 			lp->mResizeBar = resize_bar;
 			LLView::addChild(resize_bar, 0);
@@ -864,3 +929,4 @@ void LLLayoutStack::updateResizeBarLimits()
 		previous_visible_panelp = visible_panelp;
 	}
 }
+
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 02c664f1a060bbcaa51d93143d31ef4f2b168c27..b570974bd6593984b00d4c763c455b90a9c7bc36 100755
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -62,6 +62,11 @@ public:
 		Optional<F32>			open_time_constant,
 								close_time_constant;
 		Optional<S32>			resize_bar_overlap;
+		Optional<bool>			show_drag_handle;
+		Optional<S32>			drag_handle_first_indent;
+		Optional<S32>			drag_handle_second_indent;
+		Optional<S32>			drag_handle_thickness;
+		Optional<S32>			drag_handle_shift;
 
 		Params();
 	};
@@ -126,6 +131,11 @@ private:
 	F32  mCloseTimeConstant;
 	bool mNeedsLayout;
 	S32  mResizeBarOverlap;
+	bool mShowDragHandle;
+	S32  mDragHandleFirstIndent;
+	S32  mDragHandleSecondIndent;
+	S32  mDragHandleThickness;
+	S32  mDragHandleShift;
 }; // end class LLLayoutStack
 
 
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index f7bf39c897b8351e0163c8f92125084a843b3a7a..f854e1785d5d816bed315a77d64911beb3e1482c 100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3146,6 +3146,13 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size
 	const S32 CURSOR_WIDTH = 12;
 
+	if (menu->getChildList()->empty())
+	{
+		return;
+	}
+
+	menu->setVisible( TRUE );
+
 	//Do not show menu if all menu items are disabled
 	BOOL item_enabled = false;
 	for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin();
@@ -3156,8 +3163,9 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 		item_enabled = item_enabled || menu_item->getEnabled();
 	}
 
-	if(menu->getChildList()->empty() || !item_enabled)
+	if(!item_enabled)
 	{
+		menu->setVisible( FALSE );
 		return;
 	}
 
@@ -3173,8 +3181,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 		menu->mFirstVisibleItem = NULL;
 	}
 
-	menu->setVisible( TRUE );
-
 	// Fix menu rect if needed.
 	menu->needsArrange();
 	menu->arrangeAndClear();
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 1789f003b91ecd843aba930d724b22e4184e4f48..a1853ca1f787de02aec6216015af041244c3d0d2 100755
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -214,7 +214,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
 		}
 		else
 		{
-			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", TRUE);
+			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT);
 			mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name);
 		}
 	}
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 15e56cbfe5ac2542ee80759093d29aac892959e9..e67b22c977674c51d8ba8c379e3f3410b9edc56f 100755
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -28,14 +28,53 @@
 
 #include "llresizebar.h"
 
+#include "lllocalcliprect.h"
 #include "llmath.h"
 #include "llui.h"
 #include "llmenugl.h"
 #include "llfocusmgr.h"
 #include "llwindow.h"
 
+class LLImagePanel : public LLPanel
+{
+public:
+	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
+	{
+		Optional<bool> horizontal;
+		Params() : horizontal("horizontal", false) {}
+	};
+	LLImagePanel(const Params& p) : LLPanel(p), mHorizontal(p.horizontal) {}
+	virtual ~LLImagePanel() {}
+
+	void draw()
+	{
+		const LLRect& parent_rect = getParent()->getRect();
+		const LLRect& rect = getRect();
+		LLRect clip_rect( -rect.mLeft, parent_rect.getHeight() - rect.mBottom - 2
+						 , parent_rect.getWidth() - rect.mLeft - (mHorizontal ? 2 : 0), -rect.mBottom);
+		LLLocalClipRect clip(clip_rect);
+		LLPanel::draw();
+	}
+
+private:
+	bool mHorizontal;
+};
+
+static LLDefaultChildRegistry::Register<LLImagePanel> t1("resize_bar_image_panel");
+
+LLResizeBar::Params::Params()
+:	max_size("max_size", S32_MAX),
+	snapping_enabled("snapping_enabled", true),
+	resizing_view("resizing_view"),
+	side("side"),
+	allow_double_click_snapping("allow_double_click_snapping", true),
+	show_drag_handle("show_drag_handle", false)
+{
+	name = "resize_bar";
+}
+
 LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
-:	LLView(p),
+:	LLPanel(p),
 	mDragLastScreenX( 0 ),
 	mDragLastScreenY( 0 ),
 	mLastMouseScreenX( 0 ),
@@ -46,7 +85,9 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
 	mSnappingEnabled(p.snapping_enabled),
 	mAllowDoubleClickSnapping(p.allow_double_click_snapping),
 	mResizingView(p.resizing_view),
-	mResizeListener(NULL)
+	mResizeListener(NULL),
+	mShowDragHandle(p.show_drag_handle),
+	mImagePanel(NULL)
 {
 	setFollowsNone();
 	// set up some generically good follow code.
@@ -75,8 +116,37 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
 	default:
 		break;
 	}
+
+	if (mShowDragHandle)
+	{
+		LLViewBorder::Params border_params;
+		border_params.border_thickness = 1;
+		border_params.highlight_light_color = LLUIColorTable::instance().getColor("ResizebarBorderLight");
+		border_params.shadow_dark_color = LLUIColorTable::instance().getColor("ResizebarBorderDark");
+
+		addBorder(border_params);
+		setBorderVisible(TRUE);
+
+		LLImagePanel::Params image_panel;
+		mDragHandleImage = LLUI::getUIImage(LLResizeBar::RIGHT == mSide ? "Vertical Drag Handle" : "Horizontal Drag Handle");
+		image_panel.bg_alpha_image = mDragHandleImage;
+		image_panel.background_visible = true;
+		image_panel.horizontal = (LLResizeBar::BOTTOM == mSide);
+		mImagePanel = LLUICtrlFactory::create<LLImagePanel>(image_panel);
+		setImagePanel(mImagePanel);
+	}
 }
 
+BOOL LLResizeBar::postBuild()
+{
+	if (mShowDragHandle)
+	{
+		setBackgroundVisible(TRUE);
+		setTransparentColor(LLUIColorTable::instance().getColor("ResizebarBody"));
+	}
+
+	return LLPanel::postBuild();
+}
 
 BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
 {
@@ -342,3 +412,39 @@ BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+void LLResizeBar::setImagePanel(LLPanel * panelp)
+{
+	const LLView::child_list_t * children = getChildList();
+	if (getChildCount() == 2)
+	{
+		LLPanel * image_panelp = dynamic_cast<LLPanel*>(children->back());
+		if (image_panelp)
+		{
+			removeChild(image_panelp);
+			delete image_panelp;
+		}
+	}
+
+	addChild(panelp);
+	sendChildToBack(panelp);
+}
+
+LLPanel * LLResizeBar::getImagePanel() const
+{
+	return getChildCount() > 0 ? (LLPanel *)getChildList()->back() : NULL;
+}
+
+void LLResizeBar::draw()
+{
+	if (mShowDragHandle)
+	{
+		S32 image_width = mDragHandleImage->getTextureWidth();
+		S32 image_height = mDragHandleImage->getTextureHeight();
+		const LLRect& panel_rect = getRect();
+		S32 image_left = (panel_rect.getWidth() - image_width) / 2 - 1;
+		S32 image_bottom = (panel_rect.getHeight() - image_height) / 2;
+		mImagePanel->setRect(LLRect(image_left, image_bottom + image_height, image_left + image_width, image_bottom));
+	}
+
+	LLPanel::draw();
+}
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 8190a95a71b14212fa8435554eb016c45d566f52..bcf8ea0b40ea88c1b6ef76f333904a0134d2174a 100755
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -27,15 +27,14 @@
 #ifndef LL_RESIZEBAR_H
 #define LL_RESIZEBAR_H
 
-#include "llview.h"
-#include "llcoord.h"
+#include "llpanel.h"
 
-class LLResizeBar : public LLView
+class LLResizeBar : public LLPanel
 {
 public:
 	enum Side { LEFT, TOP, RIGHT, BOTTOM };
 
-	struct Params : public LLInitParam::Block<Params, LLView::Params>
+	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
 	{
 		Mandatory<LLView*> resizing_view;
 		Mandatory<Side>	side;
@@ -44,24 +43,19 @@ public:
 		Optional<S32>	max_size;
 		Optional<bool>	snapping_enabled;
 		Optional<bool>	allow_double_click_snapping;
+		Optional<bool>	show_drag_handle;
 
-		Params()
-		:	max_size("max_size", S32_MAX),
-			snapping_enabled("snapping_enabled", true),
-			resizing_view("resizing_view"),
-			side("side"),
-			allow_double_click_snapping("allow_double_click_snapping", true)
-		{
-			name = "resize_bar";
-		}
+		Params();
 	};
 
 protected:
 	LLResizeBar(const LLResizeBar::Params& p);
 	friend class LLUICtrlFactory;
+
+	/*virtual*/ BOOL postBuild();
 public:
 
-//	virtual void	draw();  No appearance
+	virtual void	draw();
 	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
@@ -72,20 +66,26 @@ public:
 	void			setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
 	bool			canResize() { return getEnabled() && mMaxSize > mMinSize; }
 	void            setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
+	BOOL			isShowDragHandle() const { return mShowDragHandle; }
+	void			setImagePanel(LLPanel * panelp);
+	LLPanel *		getImagePanel() const;
 
 private:
-	S32				mDragLastScreenX;
-	S32				mDragLastScreenY;
-	S32				mLastMouseScreenX;
-	S32				mLastMouseScreenY;
-	LLCoordGL		mLastMouseDir;
-	S32				mMinSize;
-	S32				mMaxSize;
-	const Side		mSide;
-	BOOL			mSnappingEnabled;
-	BOOL			mAllowDoubleClickSnapping;
-	LLView*			mResizingView;
-	boost::function<void(void*)>  mResizeListener;
+	S32								mDragLastScreenX;
+	S32								mDragLastScreenY;
+	S32								mLastMouseScreenX;
+	S32								mLastMouseScreenY;
+	LLCoordGL						mLastMouseDir;
+	S32								mMinSize;
+	S32								mMaxSize;
+	const Side						mSide;
+	BOOL							mSnappingEnabled;
+	BOOL							mAllowDoubleClickSnapping;
+	BOOL							mShowDragHandle;
+	LLView*							mResizingView;
+	boost::function<void(void*)>	mResizeListener;
+	LLPointer<LLUIImage>			mDragHandleImage;
+	LLPanel *						mImagePanel;
 };
 
 #endif  // LL_RESIZEBAR_H
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 4adfd42edd3f7e83dfbed91888ff7c5946fe2d8a..6e03f604a2f05de05660aae67b6b981205af427d 100755
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1183,10 +1183,10 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos)
 // Selects first enabled item of the given name.
 // Returns false if item not found.
 // Calls getItemByLabel in order to combine functionality
-BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive)
+BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive, S32 column/* = 0*/)
 {
 	deselectAllItems(TRUE); 	// ensure that no stale items are selected, even if we don't find a match
-	LLScrollListItem* item = getItemByLabel(label, case_sensitive);
+	LLScrollListItem* item = getItemByLabel(label, case_sensitive, column);
 
 	bool found = NULL != item;
 	if(found)
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 7bc558f742e4d8295043ad51fc7d9151d9e41803..c61e281a31ec61d21b38aa352e6f2b46ca4cee97 100755
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -241,7 +241,7 @@ public:
 	// one of which can be selected at a time.
 	virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
 
-	BOOL			selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE );		// FALSE if item not found
+	BOOL			selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );		// FALSE if item not found
 	BOOL			selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
 	BOOL			selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
 	LLScrollListItem*  getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index a45c4ced2eec2c1338c3f46a4df82488470c8579..3c284b3f038ef4d068c0fe48a1f473cbd9bc6701 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -180,6 +180,7 @@ LLTextBase::Params::Params()
 LLTextBase::LLTextBase(const LLTextBase::Params &p) 
 :	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
 	mURLClickSignal(NULL),
+	mIsFriendSignal(NULL),
 	mMaxTextByteLength( p.max_text_length ),
 	mFont(p.font),
 	mFontShadow(p.font_shadow),
@@ -653,6 +654,10 @@ void LLTextBase::drawText()
 			mSpellCheckEnd = end;
 		}
 	}
+	else
+	{
+		mMisspellRanges.clear();
+	}
 
 	LLTextSegmentPtr cur_segment = *seg_iter;
 
@@ -1850,7 +1855,17 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
 
 	static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
 
-	if (index > getLength()) { return mSegments.end(); }
+	S32 text_len = 0;
+	if (!useLabel())
+	{
+		text_len = getLength();
+	}
+	else
+	{
+		text_len = mLabel.getWString().length();
+	}
+
+	if (index > text_len) { return mSegments.end(); }
 
 	// when there are no segments, we return the end iterator, which must be checked by caller
 	if (mSegments.size() <= 1) { return mSegments.begin(); }
@@ -1866,7 +1881,17 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i
 {
 	static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
 
-	if (index > getLength()) { return mSegments.end(); }
+	S32 text_len = 0;
+	if (!useLabel())
+	{
+		text_len = getLength();
+	}
+	else
+	{
+		text_len = mLabel.getWString().length();
+	}
+
+	if (index > text_len) { return mSegments.end(); }
 
 	// when there are no segments, we return the end iterator, which must be checked by caller
 	if (mSegments.size() <= 1) { return mSegments.begin(); }
@@ -1916,9 +1941,12 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url));
 	registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
 	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
+	registrar.add("Url.Block", boost::bind(&LLUrlAction::blockObject, url));
 	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
 	registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
 	registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
+	registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
+	registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
 	registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
 	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
@@ -1927,6 +1955,19 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	delete mPopupMenu;
 	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
 																		 LLMenuHolderGL::child_registry_t::instance());	
+	if (mIsFriendSignal)
+	{
+		bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
+		LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
+		LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
+
+		if (addFriendButton && removeFriendButton)
+		{
+			addFriendButton->setEnabled(!isFriend);
+			removeFriendButton->setEnabled(isFriend);
+		}
+	}
+	
 	if (mPopupMenu)
 	{
 		mPopupMenu->show(x, y);
@@ -2096,7 +2137,7 @@ void LLTextBase::resetLabel()
 	}
 }
 
-bool LLTextBase::useLabel()
+bool LLTextBase::useLabel() const
 {
     return !getLength() && !mLabel.empty() && !hasFocus();
 }
@@ -2602,21 +2643,18 @@ void LLTextBase::setCursorAtLocalPos( S32 local_x, S32 local_y, bool round, bool
 void LLTextBase::changeLine( S32 delta )
 {
 	S32 line = getLineNumFromDocIndex(mCursorPos);
+	S32 max_line_nb = getLineCount() - 1;
+	max_line_nb = (max_line_nb < 0 ? 0 : max_line_nb);
+    
+	S32 new_line = llclamp(line + delta, 0, max_line_nb);
 
-	S32 new_line = line;
-	if( (delta < 0) && (line > 0 ) )
-	{
-		new_line = line - 1;
-	}
-	else if( (delta > 0) && (line < (getLineCount() - 1)) )
-	{
-		new_line = line + 1;
-	}
-
-	LLRect visible_region = getVisibleDocumentRect();
-
-	S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mRect.mBottom + mVisibleTextRect.mBottom - visible_region.mBottom, TRUE);
-	setCursorPos(new_cursor_pos, true);
+    if (new_line != line)
+    {
+        LLRect visible_region = getVisibleDocumentRect();
+        S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel,
+                                                       mLineInfoList[new_line].mRect.mBottom + mVisibleTextRect.mBottom - visible_region.mBottom, TRUE);
+        setCursorPos(new_cursor_pos, true);
+    }
 }
 
 bool LLTextBase::scrolledToStart()
@@ -2910,6 +2948,15 @@ boost::signals2::connection LLTextBase::setURLClickedCallback(const commit_signa
 	return mURLClickSignal->connect(cb);
 }
 
+boost::signals2::connection LLTextBase::setIsFriendCallback(const is_friend_signal_t::slot_type& cb)
+{
+	if (!mIsFriendSignal)
+	{
+		mIsFriendSignal = new is_friend_signal_t();
+	}
+	return mIsFriendSignal->connect(cb);
+}
+
 //
 // LLTextSegment
 //
@@ -3203,7 +3250,7 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 		: LLFontGL::ONLY_WORD_BOUNDARIES;
 	
 	
-	LLWString offsetString(text.c_str() + segment_offset + mStart);
+	S32 offsetLength = text.length() - (segment_offset + mStart);
 
 	if(getLength() < segment_offset + mStart)
 	{ 
@@ -3211,13 +3258,13 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 						<< segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << "\tmax_chars\t" << max_chars << llendl;
 	}
 
-	if(offsetString.length() + 1 < max_chars)
+	if( (offsetLength + 1) < max_chars)
 	{
-		llinfos << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetString.length():\t" << offsetString.length() << " getLength() : "
+		llinfos << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetLength:\t" << offsetLength << " getLength() : "
 			<< getLength() << "\tsegment_offset:\t" << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << llendl;
 	}
 	
-	S32 num_chars = mStyle->getFont()->maxDrawableChars(offsetString.c_str(), 
+	S32 num_chars = mStyle->getFont()->maxDrawableChars( text.c_str() + (segment_offset + mStart),
 												(F32)num_pixels,
 												max_chars, 
 												word_wrap_style);
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 20a73387b57a3193ae3dc0d5150d2a5f98d6d25b..a74e97cac836787d086301241233eecadc224f66 100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -258,6 +258,8 @@ public:
 	friend class LLNormalTextSegment;
 	friend class LLUICtrlFactory;
 
+	typedef boost::signals2::signal<bool (const LLUUID& user_id)> is_friend_signal_t;
+
 	struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
 	{
 		Alternative<F32>	multiple;
@@ -434,6 +436,7 @@ public:
 	virtual void			appendImageSegment(const LLStyle::Params& style_params);
 	virtual void			appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
 	boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
+	boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb);
 
 	void					setWordWrap(bool wrap);
 	LLScrollContainer*		getScrollContainer() const { return mScroller; }
@@ -507,7 +510,7 @@ protected:
 	void							initFromParams(const Params& p);
     virtual void					beforeValueChange();
 	virtual void					onValueChange(S32 start, S32 end);
-    virtual bool                    useLabel();
+    virtual bool                    useLabel() const;
 
 	// draw methods
 	void							drawSelectionBackground(); // draws the black box behind the selected text
@@ -648,6 +651,9 @@ protected:
 	// Fired when a URL link is clicked
 	commit_signal_t*			mURLClickSignal;
 
+	// Used to check if user with given ID is avatar's friend
+	is_friend_signal_t*         mIsFriendSignal;
+
 	LLUIString					mLabel;	// text label that is visible when no user text provided
 };
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 834f21309707f71d92f85d9cd2978d62b394fb17..0c16e06109fbd51b21eea8484785201adcc9d978 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1125,7 +1125,8 @@ void LLTextEditor::addChar(llwchar wc)
 	}
 }
 
-void LLTextEditor::addLineBreakChar()
+
+void LLTextEditor::addLineBreakChar(BOOL group_together)
 {
 	if( !getEnabled() )
 	{
@@ -1143,7 +1144,7 @@ void LLTextEditor::addLineBreakChar()
 	LLStyleConstSP sp(new LLStyle(LLStyle::Params()));
 	LLTextSegmentPtr segment = new LLLineBreakTextSegment(sp, mCursorPos);
 
-	S32 pos = execute(new TextCmdAddChar(mCursorPos, FALSE, '\n', segment));
+	S32 pos = execute(new TextCmdAddChar(mCursorPos, group_together, '\n', segment));
 	
 	setCursorPos(mCursorPos + pos);
 }
@@ -1484,21 +1485,28 @@ void LLTextEditor::pasteTextWithLinebreaks(LLWString & clean_string)
 	std::basic_string<llwchar>::size_type start = 0;
 	std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start);
 	
-	while(pos!=-1)
+	while((pos != -1) && (pos != clean_string.length() -1))
 	{
 		if(pos!=start)
 		{
 			std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,pos-start);
-			setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+			setCursorPos(mCursorPos + insert(mCursorPos, str, TRUE, LLTextSegmentPtr()));
 		}
-		addLineBreakChar();
-		
+		addLineBreakChar(TRUE);			// Add a line break and group with the next addition.
+
 		start = pos+1;
 		pos = clean_string.find('\n',start);
 	}
 
-	std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
-	setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+	if (pos != start)
+	{
+		std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
+		setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+	}
+	else
+	{
+		addLineBreakChar(FALSE);		// Add a line break and end the grouping.
+	}
 }
 
 // copy selection to primary
@@ -1964,8 +1972,7 @@ void LLTextEditor::onFocusReceived()
 	updateAllowingLanguageInput();
 }
 
-// virtual, from LLView
-void LLTextEditor::onFocusLost()
+void LLTextEditor::focusLostHelper()
 {
 	updateAllowingLanguageInput();
 
@@ -1982,7 +1989,11 @@ void LLTextEditor::onFocusLost()
 
 	// Make sure cursor is shown again
 	getWindow()->showCursorFromMouseMove();
+}
 
+void LLTextEditor::onFocusLost()
+{
+	focusLostHelper();
 	LLTextBase::onFocusLost();
 }
 
@@ -2128,12 +2139,17 @@ void LLTextEditor::drawPreeditMarker()
 					continue;
 				}
 
-				S32 preedit_left = mVisibleTextRect.mLeft;
+				line_info& line = mLineInfoList[cur_line];
+				LLRect text_rect(line.mRect);
+				text_rect.mRight = mDocumentView->getRect().getWidth(); // clamp right edge to document extents
+				text_rect.translate(mDocumentView->getRect().mLeft, mDocumentView->getRect().mBottom); // adjust by scroll position
+
+				S32 preedit_left = text_rect.mLeft;
 				if (left > line_start)
 				{
 					preedit_left += mFont->getWidth(text, line_start, left - line_start);
 				}
-				S32 preedit_right = mVisibleTextRect.mLeft;
+				S32 preedit_right = text_rect.mLeft;
 				if (right < line_end)
 				{
 					preedit_right += mFont->getWidth(text, line_start, right - line_start);
@@ -2146,18 +2162,18 @@ void LLTextEditor::drawPreeditMarker()
 				if (mPreeditStandouts[i])
 				{
 					gl_rect_2d(preedit_left + preedit_standout_gap,
-							line_y + preedit_standout_position,
-							preedit_right - preedit_standout_gap - 1,
-							line_y + preedit_standout_position - preedit_standout_thickness,
-							(mCursorColor.get() * preedit_standout_brightness + mWriteableBgColor.get() * (1 - preedit_standout_brightness)).setAlpha(1.0f));
+							   text_rect.mBottom + mFont->getDescenderHeight() - 1,
+							   preedit_right - preedit_standout_gap - 1,
+							   text_rect.mBottom + mFont->getDescenderHeight() - 1 - preedit_standout_thickness,
+							   (mCursorColor.get() * preedit_standout_brightness + mWriteableBgColor.get() * (1 - preedit_standout_brightness)).setAlpha(1.0f));
 				}
 				else
 				{
 					gl_rect_2d(preedit_left + preedit_marker_gap,
-							line_y + preedit_marker_position,
-							preedit_right - preedit_marker_gap - 1,
-							line_y + preedit_marker_position - preedit_marker_thickness,
-							(mCursorColor.get() * preedit_marker_brightness + mWriteableBgColor.get() * (1 - preedit_marker_brightness)).setAlpha(1.0f));
+							   text_rect.mBottom + mFont->getDescenderHeight() - 1,
+							   preedit_right - preedit_marker_gap - 1,
+							   text_rect.mBottom + mFont->getDescenderHeight() - 1 - preedit_marker_thickness,
+							   (mCursorColor.get() * preedit_marker_brightness + mWriteableBgColor.get() * (1 - preedit_marker_brightness)).setAlpha(1.0f));
 				}
 			}
 		}
@@ -2240,12 +2256,13 @@ void LLTextEditor::draw()
 		LLRect clip_rect(mVisibleTextRect);
 		clip_rect.stretch(1);
 		LLLocalClipRect clip(clip_rect);
-		drawPreeditMarker();
 	}
 
 	LLTextBase::draw();
 	drawLineNumbers();
 
+    drawPreeditMarker();
+
 	//RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret
 	// when in readonly mode
 	mBorder->setKeyboardFocusHighlight( hasFocus() );// && !mReadOnly);
@@ -2695,14 +2712,20 @@ BOOL LLTextEditor::hasPreeditString() const
 
 void LLTextEditor::resetPreedit()
 {
+    if (hasSelection())
+    {
+		if (hasPreeditString())
+        {
+            llwarns << "Preedit and selection!" << llendl;
+            deselect();
+        }
+        else
+        {
+            deleteSelection(TRUE);
+        }
+    }
 	if (hasPreeditString())
 	{
-		if (hasSelection())
-		{
-			llwarns << "Preedit and selection!" << llendl;
-			deselect();
-		}
-
 		setCursorPos(mPreeditPositions.front());
 		removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos);
 		insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString);
@@ -2750,7 +2773,10 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
 	{
 		mPreeditOverwrittenWString.clear();
 	}
-	insertStringNoUndo(insert_preedit_at, mPreeditWString);
+    
+	segment_vec_t segments;
+	//pass empty segments to let "insertStringNoUndo" make new LLNormalTextSegment and insert it, if needed.
+	insertStringNoUndo(insert_preedit_at, mPreeditWString, &segments); 
 
 	mPreeditStandouts = preedit_standouts;
 
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 969e0727047f7ff4659d9783bd91914e3229b42b..32b543ec0e3439380847c001ee18f4cefb3dece0 100755
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -248,13 +248,14 @@ protected:
 	// Undoable operations
 	void			addChar(llwchar c); // at mCursorPos
 	S32				addChar(S32 pos, llwchar wc);
-	void			addLineBreakChar();
+	void			addLineBreakChar(BOOL group_together = FALSE);
 	S32				overwriteChar(S32 pos, llwchar wc);
 	void			removeChar();
 	S32 			removeChar(S32 pos);
 	S32				insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
 	S32				remove(S32 pos, S32 length, bool group_with_next_op);
 	
+	void			focusLostHelper();
 	void			updateAllowingLanguageInput();
 	BOOL			hasPreeditString() const;
 
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 3d9f5cbbc232822be501c93860ec10342c2a0a15..928e82cb8c21c798e2cdb1744270ababa2b7012c 100755
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -381,7 +381,7 @@ bool LLToolBar::stopCommandInProgress(const LLCommandId& commandId)
 	return (command_button != NULL);
 }
 
-bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash)
+bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing/* = false */)
 {
 	LLButton * command_button = NULL;
 
@@ -391,7 +391,7 @@ bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash)
 		if (it != mButtonMap.end())
 		{
 			command_button = it->second;
-			command_button->setFlashing(flash ? TRUE : FALSE);
+			command_button->setFlashing((BOOL)(flash),(BOOL)(force_flashing));
 		}
 	}
 
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 31424a36d47a748b409d802e883d314aa550b8a9..743951a41f233bb80cc1e227da39ce5bd68033ec 100755
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -192,7 +192,7 @@ public:
 	bool hasCommand(const LLCommandId& commandId) const;	// is this command bound to a button in this toolbar
 	bool enableCommand(const LLCommandId& commandId, bool enabled);	// enable/disable button bound to the specified command, if it exists in this toolbar
 	bool stopCommandInProgress(const LLCommandId& commandId);	// stop command if it is currently active
-	bool flashCommand(const LLCommandId& commandId, bool flash); // flash button associated with given command, if in this toolbar
+	bool flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing = false); // flash button associated with given command, if in this toolbar
 
 	void setStartDragCallback(tool_startdrag_callback_t cb)   { mStartDragItemCallback  = cb; } // connects drag and drop behavior to external logic
 	void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index f51aeaec1315b56e1fa4c560cd4fc4a6305ce201..23e574cb74f26ddf86e9eb12581b2f2ef453b34f 100755
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -170,6 +170,30 @@ std::string LLUrlAction::getUserID(std::string url)
 	return id_str;
 }
 
+std::string LLUrlAction::getObjectId(std::string url)
+{
+	LLURI uri(url);
+	LLSD path_array = uri.pathArray();
+	std::string id_str;
+	if (path_array.size() >= 3)
+	{
+		id_str = path_array.get(2).asString();
+	}
+	return id_str;
+}
+
+std::string LLUrlAction::getObjectName(std::string url)
+{
+	LLURI uri(url);
+	LLSD query_map = uri.queryMap();
+	std::string name;
+	if (query_map.has("name"))
+	{
+		name = query_map["name"].asString();
+	}
+	return name;
+}
+
 void LLUrlAction::sendIM(std::string url)
 {
 	std::string id_str = getUserID(url);
@@ -188,3 +212,21 @@ void LLUrlAction::addFriend(std::string url)
 	}
 }
 
+void LLUrlAction::removeFriend(std::string url)
+{
+	std::string id_str = getUserID(url);
+	if (LLUUID::validate(id_str))
+	{
+		executeSLURL("secondlife:///app/agent/" + id_str + "/removefriend");
+	}
+}
+
+void LLUrlAction::blockObject(std::string url)
+{
+	std::string object_id = getObjectId(url);
+	std::string object_name = getObjectName(url);
+	if (LLUUID::validate(object_id))
+	{
+		executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + object_name);
+	}
+}
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index e31cd71a20769acd176ab616a3ce37160a93c6d9..e731376b95e03d6419ed3f1a29e14344ac15d486 100755
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -77,8 +77,12 @@ public:
 	/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
 	static void showProfile(std::string url);
 	static std::string getUserID(std::string url);
+	static std::string getObjectName(std::string url);
+	static std::string getObjectId(std::string url);
 	static void sendIM(std::string url);
 	static void addFriend(std::string url);
+	static void removeFriend(std::string url);
+	static void blockObject(std::string url);
 
 	/// specify the callbacks to enable this class's functionality
 	typedef boost::function<void (const std::string&)> url_callback_t;
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 99ee6888889be5b03cfb9558a2012f9bf704d8ad..b1cc502c4bbf881222d58aed55080d55c0b1ff5f 100755
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -504,6 +504,10 @@ std::string localize_slapp_label(const std::string& url, const std::string& full
 	{
 		return LLTrans::getString("SLappAgentRequestFriend") + " " + full_name;
 	}
+	if (LLStringUtil::endsWith(url, "/removefriend"))
+	{
+		return LLTrans::getString("SLappAgentRemoveFriend") + " " + full_name;
+	}
 	return full_name;
 }
 
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index cc10ed5bbd02501f5da65037a4a8f735ab16404f..e02bf552aadccfd7b38dc83f26346cf7a18f04bb 100755
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -32,7 +32,7 @@
 #define MAX_PATH MAXPATHLEN
 #endif
 
-// these numbers *may* get serialized (really??), so we need to be explicit
+// these numbers are read from settings_files.xml, so we need to be explicit
 typedef enum ELLPath
 {
 	LL_PATH_NONE = 0,
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 43c0090993ee7774b352350c65df3abd6ff10a6f..30f5526500b494feca83bec85f39e0137a940b28 100755
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -159,9 +159,8 @@ LLWinImm LLWinImm::sTheInstance;
 LLWinImm::LLWinImm() : mHImmDll(NULL)
 {
 	// Check system metrics 
-	if ( !GetSystemMetrics( SM_DBCSENABLED ) )
+	if ( !GetSystemMetrics( SM_IMMENABLED ) )
 		return;
-	
 
 	mHImmDll = LoadLibraryA("Imm32");
 	if (mHImmDll != NULL)
@@ -3500,19 +3499,11 @@ void LLWindowWin32::updateLanguageTextInputArea()
 
 void LLWindowWin32::interruptLanguageTextInput()
 {
-	if (mPreeditor)
+	if (mPreeditor && LLWinImm::isAvailable())
 	{
-		if (LLWinImm::isAvailable())
-		{
-			HIMC himc = LLWinImm::getContext(mWindowHandle);
-			LLWinImm::notifyIME(himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
-			LLWinImm::releaseContext(mWindowHandle, himc);
-		}
-
-		// Win32 document says there will be no composition string
-		// after NI_COMPOSITIONSTR returns.  The following call to
-		// resetPreedit should be a NOP unless IME goes mad...
-		mPreeditor->resetPreedit();
+		HIMC himc = LLWinImm::getContext(mWindowHandle);
+		LLWinImm::notifyIME(himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+		LLWinImm::releaseContext(mWindowHandle, himc);
 	}
 }
 
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 666c03e9fffc89295d0549544d0c3c18e9382104..16f22907872f01a7b3fbedc454716285145ee665 100755
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -132,14 +132,14 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
 
 LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
 							 LLSD initial, const std::string& comment,
-							 bool persist, bool hidefromsettingseditor)
+							 ePersist persist, bool hidefromsettingseditor)
 	: mName(name),
 	  mComment(comment),
 	  mType(type),
 	  mPersist(persist),
 	  mHideFromSettingsEditor(hidefromsettingseditor)
 {
-	if (mPersist && mComment.empty())
+	if ((persist != PERSIST_NO) && mComment.empty())
 	{
 		llerrs << "Must supply a comment for control " << mName << llendl;
 	}
@@ -260,7 +260,7 @@ void LLControlVariable::setDefaultValue(const LLSD& value)
 	}
 }
 
-void LLControlVariable::setPersist(bool state)
+void LLControlVariable::setPersist(ePersist state)
 {
 	mPersist = state;
 }
@@ -292,10 +292,29 @@ void LLControlVariable::resetToDefault(bool fire_signal)
 	}
 }
 
-bool LLControlVariable::isSaveValueDefault()
-{ 
-    return (mValues.size() ==  1) 
-        || ((mValues.size() > 1) && llsd_compare(mValues[1], mValues[0]));
+bool LLControlVariable::shouldSave(bool nondefault_only)
+{
+	// This method is used to decide whether we should save a given
+	// variable. Two of the three values of mPersist are easy.
+	if (mPersist == PERSIST_NO)
+		return false;
+
+	if (mPersist == PERSIST_ALWAYS)
+		return true;
+
+	// PERSIST_NONDFT
+	// If caller doesn't need us to filter, just save.
+	if (! nondefault_only)
+		return true;
+
+	// PERSIST_NONDFT: caller only wants us to save this variable if its value
+	// differs from default.
+	if (isDefault())                // never been altered
+		return false;
+
+	// We've set at least one other value: compare it to default. Save only if
+	// they differ.
+	return ! llsd_compare(getSaveValue(), getDefault());
 }
 
 LLSD LLControlVariable::getSaveValue() const
@@ -355,12 +374,12 @@ std::string LLControlGroup::typeEnumToString(eControlType typeenum)
 	return mTypeString[typeenum];
 }
 
-BOOL LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor)
+LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor)
 {
 	LLControlVariable* existing_control = getControl(name);
 	if (existing_control)
  	{
-		if (persist && existing_control->isType(type))
+		if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type))
 		{
 			if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val))
 			{
@@ -374,66 +393,66 @@ BOOL LLControlGroup::declareControl(const std::string& name, eControlType type,
 		{
 			llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;
 		}
- 		return TRUE;
+ 		return existing_control;
 	}
 
 	// if not, create the control and add it to the name table
 	LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor);
 	mNameTable[name] = control;	
-	return TRUE;
+	return control;
 }
 
-BOOL LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_S32, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_F32, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_STRING, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
 {
 	return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
 {
 	return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
 {
 	return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
 }
@@ -664,11 +683,11 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
 			switch(declare_as)
 			{
 			case TYPE_COL4:
-				declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST);
+				declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO);
 				break;
 			case TYPE_STRING:
 			default:
-				declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST);
+				declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO);
 				break;
 			}
 		}
@@ -805,21 +824,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
 		{
 			llwarns << "Tried to save invalid control: " << iter->first << llendl;
 		}
-
-		if( control && control->isPersisted() )
+		else if( control->shouldSave(nondefault_only) )
 		{
-			if (!(nondefault_only && (control->isSaveValueDefault())))
-			{
-				settings[iter->first]["Type"] = typeEnumToString(control->type());
-				settings[iter->first]["Comment"] = control->getComment();
-				settings[iter->first]["Value"] = control->getSaveValue();
-				++num_saved;
-			}
-			else
-			{
-				// Debug spam
-				// llinfos << "Skipping " << control->getName() << llendl;
-			}
+			settings[iter->first]["Type"] = typeEnumToString(control->type());
+			settings[iter->first]["Comment"] = control->getComment();
+			settings[iter->first]["Value"] = control->getSaveValue();
+			++num_saved;
 		}
 	}
 	llofstream file;
@@ -862,13 +872,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 	
 	for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)
 	{
-		bool persist = true;
+		LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT;
 		std::string const & name = itr->first;
 		LLSD const & control_map = itr->second;
 		
 		if(control_map.has("Persist")) 
 		{
-			persist = control_map["Persist"].asInteger();
+			persist = control_map["Persist"].asInteger()?
+					  LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO;
 		}
 		
 		// Sometimes we want to use the settings system to provide cheap persistence, but we
@@ -887,6 +898,8 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		LLControlVariable* existing_control = getControl(name);
 		if(existing_control)
 		{
+			// set_default_values is true when we're loading the initial,
+			// immutable files from app_settings, e.g. settings.xml.
 			if(set_default_values)
 			{
 				// Override all previously set properties of this control.
@@ -908,6 +921,9 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 			}
 			else if(existing_control->isPersisted())
 			{
+				// save_values is specifically false for (e.g.)
+				// SessionSettingsFile and UserSessionSettingsFile -- in other
+				// words, for a file that's supposed to be transient.
 				existing_control->setValue(control_map["Value"], save_values);
 			}
 			// *NOTE: If not persisted and not setting defaults, 
@@ -915,6 +931,39 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		}
 		else
 		{
+			// We've never seen this control before. Either we're loading up
+			// the initial set of default settings files (set_default_values)
+			// -- or we're loading user settings last saved by a viewer that
+			// supports a superset of the variables we know.
+			// CHOP-962: if we're loading an unrecognized user setting, make
+			// sure we save it later. If you try an experimental viewer, tweak
+			// a new setting, briefly revert to an old viewer, then return to
+			// the new one, we don't want the old viewer to discard the
+			// setting you changed.
+			if (! set_default_values)
+			{
+				// Using PERSIST_ALWAYS insists that saveToFile() (which calls
+				// LLControlVariable::shouldSave()) must save this control
+				// variable regardless of its value. We can safely set this
+				// LLControlVariable persistent because the 'persistent' flag
+				// is not itself persisted!
+				persist = LLControlVariable::PERSIST_ALWAYS;
+				// We want to mention unrecognized user settings variables
+				// (e.g. from a newer version of the viewer) in the log. But
+				// we also arrive here for Boolean variables generated by
+				// the notifications subsystem when the user checks "Don't
+				// show me this again." These aren't declared in settings.xml;
+				// they're actually named for the notification they suppress.
+				// We don't want to mention those. Apologies, this is a bit of
+				// a hack: we happen to know that user settings go into an
+				// LLControlGroup whose name is "Global".
+				if (getKey() == "Global")
+				{
+					LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey()
+											   << " settings variable " << name << LL_ENDL;
+				}
+			}
+
 			declareControl(name, 
 						   typeStringToEnum(control_map["Type"].asString()), 
 						   control_map["Value"], 
@@ -923,7 +972,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 						   hidefromsettingseditor
 						   );
 		}
-		
+
 		++validitems;
 	}
 
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index ee7d1d50b7e1de8cb81e372330c9de128fda49ec..e1f9be80ddad26d909449b0a6300f4d50c08b553 100755
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -72,8 +72,6 @@ class LLVector3d;
 class LLColor4;
 class LLColor3;
 
-const BOOL NO_PERSIST = FALSE;
-
 typedef enum e_control_type
 {
 	TYPE_U32 = 0,
@@ -100,21 +98,28 @@ public:
 	typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
 	typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t;
 
+	enum ePersist
+	{
+		PERSIST_NO,                 // don't save this var
+		PERSIST_NONDFT,             // save this var if differs from default
+		PERSIST_ALWAYS              // save this var even if has default value
+	};
+
 private:
 	std::string		mName;
 	std::string		mComment;
 	eControlType	mType;
-	bool			mPersist;
+	ePersist		mPersist;
 	bool			mHideFromSettingsEditor;
 	std::vector<LLSD> mValues;
-	
+
 	commit_signal_t mCommitSignal;
 	validate_signal_t mValidateSignal;
 	
 public:
 	LLControlVariable(const std::string& name, eControlType type,
 					  LLSD initial, const std::string& comment,
-					  bool persist = true, bool hidefromsettingseditor = false);
+					  ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false);
 
 	virtual ~LLControlVariable();
 	
@@ -131,8 +136,8 @@ public:
 	validate_signal_t* getValidateSignal() { return &mValidateSignal; }
 
 	bool isDefault() { return (mValues.size() == 1); }
-	bool isSaveValueDefault();
-	bool isPersisted() { return mPersist; }
+	bool shouldSave(bool nondefault_only);
+	bool isPersisted() { return mPersist != PERSIST_NO; }
 	bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }
 	LLSD get()			const	{ return getValue(); }
 	LLSD getValue()		const	{ return mValues.back(); }
@@ -142,7 +147,7 @@ public:
 	void set(const LLSD& val)	{ setValue(val); }
 	void setValue(const LLSD& value, bool saved_value = TRUE);
 	void setDefaultValue(const LLSD& value);
-	void setPersist(bool state);
+	void setPersist(ePersist);
 	void setHiddenFromSettingsEditor(bool hide);
 	void setComment(const std::string& comment);
 
@@ -207,19 +212,19 @@ public:
 		virtual void apply(const std::string& name, LLControlVariable* control) = 0;
 	};
 	void applyToAll(ApplyFunctor* func);
-	
-	BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE);
-	BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  BOOL persist = TRUE);
-	BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
+
+	LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE);
+	LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
 
 	std::string getString(const std::string& name);
 	std::string getText(const std::string& name);
@@ -368,7 +373,7 @@ private:
 		init_value = convert_to_llsd(default_value);
 		if(type < TYPE_COUNT)
 		{
-			group.declareControl(name, type, init_value, comment, FALSE);
+			group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO);
 			return true;
 		}
 		return false;
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index ede81956ec6879b896ba09be308211f1b002fc67..c273773c9b43a9223dfc43fc7dba44bb76f67934 100755
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -128,7 +128,11 @@ namespace tut
 	template<> template<>
 	void control_group_t::test<3>()
 	{
-		int results = mCG->loadFromFile(mTestConfigFile.c_str());
+		// Pass default_values = true. This tells loadFromFile() we're loading
+		// a default settings file that declares variables, rather than a user
+		// settings file. When loadFromFile() encounters an unrecognized user
+		// settings variable, it forcibly preserves it (CHOP-962).
+		int results = mCG->loadFromFile(mTestConfigFile.c_str(), true);
 		LLControlVariable* control = mCG->getControl("TestSetting");
 		LLSD new_value = 13;
 		control->setValue(new_value, FALSE);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 89add3e21f776cac6682af572fc9bdb5bfe95a52..e2ae7a5a9af1e64abdb98c8e7d23ce7badcb1f47 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -229,6 +229,7 @@ set(viewer_SOURCE_FILES
     llfloaterfonttest.cpp
     llfloatergesture.cpp
     llfloatergodtools.cpp
+    llfloatergotoline.cpp
     llfloatergroupinvite.cpp
     llfloatergroups.cpp
     llfloaterhandler.cpp
@@ -812,6 +813,7 @@ set(viewer_HEADER_FILES
     llfloaterfonttest.h
     llfloatergesture.h
     llfloatergodtools.h
+    llfloatergotoline.h
     llfloatergroupinvite.h
     llfloatergroups.h
     llfloaterhandler.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 0f44168a4d54427731b95473ed03e4730fe645b6..d15b8b06fa347d6fdb062184febdbe5fef95c4ad 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.6.4
+3.6.5
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 7ab7787d77c874b1b3d075001e3e621023a45664..a9f6079630342966ea96a365eb43079bf9e55f1c 100755
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -22,7 +22,8 @@
     <map>
       <key>count</key>
       <integer>1</integer>
-      <!-- Special case. Not mapped to a setting. -->
+      <key>map-to</key>
+      <string>CmdLineChannel</string>
     </map>
 
     <key>console</key>
@@ -96,6 +97,8 @@
 0 - low, 1 - medium, 2 - high, 3 - ultra</string>
       <key>count</key>
       <integer>1</integer>
+      <key>map-to</key>
+      <string>RenderQualityPerformance</string>
     </map>
 
     <key>grid</key>
@@ -108,6 +111,16 @@
       <string>CmdLineGridChoice</string>
     </map>
 
+    <key>update-service</key>
+    <map>
+      <key>desc</key>
+      <string>Override the url base for the update query.</string>
+      <key>count</key>
+      <integer>1</integer>
+      <key>map-to</key>
+      <string>CmdLineUpdateService</string>
+    </map>
+
     <key>help</key>
     <map>
       <key>desc</key>
@@ -370,7 +383,8 @@
       <boolean>true</boolean>
       <key>last_option</key>
       <boolean>true</boolean>
-      <!-- Special case. Not mapped to a setting. -->
+      <key>map-to</key>
+      <string>CmdLineLoginLocation</string>
     </map>
 
     <key>url</key>
@@ -381,7 +395,8 @@
       <integer>1</integer>
       <key>last_option</key>
       <boolean>true</boolean>
-      <!-- Special case. Not mapped to a setting. -->
+      <key>map-to</key>
+      <string>CmdLineLoginLocation</string>
     </map>
 
     <key>usersessionsettings</key>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 72916ccf8cc0d5d341eaea32b0dfb96a1aea218e..72fe21cf14be78b8d82f77bf2ed220082c78e8d0 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -126,6 +126,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>AnalyzePerformance</key>
+    <map>
+      <key>Comment</key>
+      <string>Request performance analysis for a particular viewer run</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AnimateTextures</key>
     <map>
       <key>Comment</key>
@@ -1738,6 +1749,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>CmdLineChannel</key>
+    <map>
+      <key>Comment</key>
+      <string>Command line specified channel name</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
+    </map>
     <key>CmdLineDisableVoice</key>
     <map>
       <key>Comment</key>
@@ -1760,6 +1782,17 @@
       <key>Value</key>
       <string />
     </map>
+    <key>CmdLineUpdateService</key>
+    <map>
+      <key>Comment</key>
+      <string>Override the url base for the update query.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
+    </map>
     <key>CmdLineHelperURI</key>
     <map>
       <key>Comment</key>
@@ -1784,6 +1817,17 @@
         <string />
       </array>
     </map>
+    <key>CmdLineLoginLocation</key>
+    <map>
+      <key>Comment</key>
+      <string>Startup destination requested on command line</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string/>
+    </map>
     <key>ConnectAsGod</key>
     <map>
       <key>Comment</key>
@@ -1916,6 +1960,17 @@
       <key>Value</key>
       <integer>262144</integer>
     </map>
+    <key>CrashOnStartup</key>
+    <map>
+      <key>Comment</key>
+      <string>User-requested crash on viewer startup</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>CreateToolCopyCenters</key>
     <map>
       <key>Comment</key>
@@ -2158,6 +2213,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DebugSession</key>
+    <map>
+      <key>Comment</key>
+      <string>Request debugging for a particular viewer session</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DebugShowColor</key>
     <map>
       <key>Comment</key>
@@ -2972,6 +3038,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DisableCrashLogger</key>
+    <map>
+      <key>Comment</key>
+      <string>Do not send crash report to Linden server</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DisableMouseWarp</key>
     <map>
       <key>Comment</key>
@@ -3489,16 +3566,27 @@
         <key>Value</key>
             <real>10.0</real>
         </map>
-    <key>FilterItemsPerFrame</key>
+    <key>FilterItemsMaxTimePerFrameVisible</key>
     <map>
-      <key>Comment</key>
-      <string>Maximum number of inventory items to match against search filter every frame (lower to increase framerate while searching, higher to improve search speed)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>S32</string>
-      <key>Value</key>
-      <integer>500</integer>
+        <key>Comment</key>
+        <string>Max time devoted to items filtering per frame for visible inventory listings (in milliseconds)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>S32</string>
+        <key>Value</key>
+        <integer>10</integer>
+    </map>
+    <key>FilterItemsMaxTimePerFrameUnvisible</key>
+    <map>
+        <key>Comment</key>
+        <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>S32</string>
+        <key>Value</key>
+        <integer>1</integer>
     </map>
     <key>FindLandArea</key>
     <map>
@@ -5217,6 +5305,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>LogMetrics</key>
+    <map>
+      <key>Comment</key>
+      <string>Log viewer metrics</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string/>
+    </map>
+    <key>LogPerformance</key>
+    <map>
+      <key>Comment</key>
+      <string>Log performance analysis for a particular viewer run</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LogTextureNetworkTraffic</key>
     <map>
       <key>Comment</key>
@@ -6394,6 +6504,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>NoQuickTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable QuickTime for a particular viewer run</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>NoVerifySSLCert</key>
     <map>
       <key>Comment</key>
@@ -6430,7 +6551,10 @@
     <key>NotificationConferenceIMOptions</key>
     <map>
       <key>Comment</key>
-      <string>Specifies how the UI responds to Conference IM Notifications.</string>
+      <string>
+        Specifies how the UI responds to Conference IM Notifications.
+        Allowed values: [openconversations,toast,flash,noaction]
+      </string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6441,7 +6565,10 @@
     <key>NotificationFriendIMOptions</key>
     <map>
       <key>Comment</key>
-      <string>Specifies how the UI responds to Friend IM Notifications.</string>
+      <string>
+        Specifies how the UI responds to Friend IM Notifications.
+        Allowed values: [openconversations,toast,flash,noaction]
+      </string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6452,7 +6579,10 @@
     <key>NotificationGroupChatOptions</key>
     <map>
       <key>Comment</key>
-      <string>Specifies how the UI responds to Group Chat Notifications.</string>
+      <string>
+        Specifies how the UI responds to Group Chat Notifications.
+        Allowed values: [openconversations,toast,flash,noaction]
+      </string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6463,7 +6593,10 @@
     <key>NotificationNearbyChatOptions</key>
     <map>
       <key>Comment</key>
-      <string>Specifies how the UI responds to Nearby Chat Notifications.</string>
+      <string>
+        Specifies how the UI responds to Nearby Chat Notifications.
+        Allowed values: [openconversations,toast,flash,noaction]
+      </string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6474,7 +6607,24 @@
     <key>NotificationNonFriendIMOptions</key>
     <map>
       <key>Comment</key>
-      <string>Specifies how the UI responds to Non Friend IM Notifications.</string>
+      <string>
+        Specifies how the UI responds to Non Friend IM Notifications.
+        Allowed values: [openconversations,toast,flash,noaction]
+      </string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>toast</string>
+    </map>  
+    <key>NotificationObjectIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>
+        Specifies how the UI responds to Object IM Notifications.
+        Allowed values: [openconversations,toast,flash,noaction]
+      </string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -6987,6 +7137,17 @@
       <key>Value</key>
       <real>90.0</real>
     </map>
+    <key>PlayChatAnim</key>
+    <map>
+      <key>Comment</key>
+      <string>Your avatar plays the chat animation whenever you say, shout or whisper something in nearby chat</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>PlayTypingAnim</key>
     <map>
       <key>Comment</key>
@@ -7020,6 +7181,72 @@
       <key>Value</key>
       <integer>0</integer>
     </map>  
+    <key>PlaySoundFriendIM</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when friend's IM received.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>PlaySoundNonFriendIM</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when non-friend's IM received.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>PlaySoundConferenceIM</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when conference IM received.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>PlaySoundGroupChatIM</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when group chat IM received.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>PlaySoundNearbyChatIM</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when nearby chat IM received.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>PlaySoundObjectIM</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when IM fom an object received.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>PlaySoundNewConversation</key>
     <map>
       <key>Comment</key>
@@ -9654,6 +9881,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>ReplaySession</key>
+    <map>
+      <key>Comment</key>
+      <string>Request replay of previously-recorded pilot file</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RotateRight</key>
     <map>
       <key>Comment</key>
@@ -12870,12 +13108,13 @@
     <key>UserLoginInfo</key>
     <map>
       <key>Comment</key>
-      <string>Users loging data.</string>
+      <string>User login data.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
       <string>LLSD</string>
       <key>Value</key>
+      <string/>
     </map>
     <key>VFSOldSize</key>
     <map>
diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml
index bfc09286e39abd63cadb21d20bf4928230fa690b..4a9e522a96dd036cef7e29b96580d390bb02f539 100755
--- a/indra/newview/app_settings/settings_files.xml
+++ b/indra/newview/app_settings/settings_files.xml
@@ -4,6 +4,9 @@
     <file name="Global"
           file_name="settings.xml"
           required="true"/>
+    <file name="Global"
+          file_name="settings_install.xml"
+          required="false"/>
     <file name="PerAccount"
           file_name="settings_per_account.xml"
           required="true"/>
diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml
index 01a70f267132f34bfe0cae54c55a46627b5efb44..e660c1a33b060c29d5d7f7771aea4e8e3a7d5b5b 100755
--- a/indra/newview/app_settings/settings_minimal.xml
+++ b/indra/newview/app_settings/settings_minimal.xml
@@ -1 +1,4 @@
-<llsd/>
\ No newline at end of file
+<?xml version="1.0"?>
+<llsd>
+  <undef/>
+</llsd>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 590f41283b68eb9d94c04af1ae5c00dae70c77a0..636caf5ef321cd69a50cb381609e6745ab26889f 100755
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -109,18 +109,7 @@
             <string>Boolean</string>
         <key>Value</key>
             <integer>0</integer>
-    </map>
-    <key>DisplayDestinationsOnInitialRun</key>
-        <map>
-        <key>Comment</key>
-          <string>Display the destinations guide when a user first launches Second Life.</string>
-        <key>Persist</key>
-          <integer>1</integer>
-        <key>Type</key>
-          <string>Boolean</string>
-        <key>Value</key>
-          <integer>1</integer>
-        </map>
+    </map>    
     <key>LastInventoryInboxActivity</key>
         <map>
         <key>Comment</key>
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index d8440eebf1c54c4b8a1f687a666285229c71c330..c23401d5a661fd954536fadf9c9b8fa0c7da3779 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -121,37 +121,21 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
 
 export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
 
-# Have to deal specially with gridargs.dat; typical contents look like:
-# --channel "Second Life Test"  --settings settings_test.xml
-# Simply embedding $(<etc/gridargs.dat) into a command line treats each of
-# Second, Life and Developer as separate args -- no good. We need bash to
-# process quotes using eval.
-# First, check if we have been instructed to skip reading in gridargs.dat:
-skip_gridargs=false
-argnum=0
+# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch.
+# The gridargs.dat file is no more, but we still want to avoid breaking
+# scripts that invoke this one with --skip-gridargs.
+ARGS=()
 for ARG in "$@"; do
-    if [ "--skip-gridargs" == "$ARG" ]; then
-        skip_gridargs=true
-    else
-        ARGS[$argnum]="$ARG"
-        argnum=$(($argnum+1))
+    if [ "--skip-gridargs" != "$ARG" ]; then
+        ARGS[${#ARGS[*]}]="$ARG"
     fi
 done
 
-# Second, read it without scanning, then scan that string. Break quoted words
-# into a bash array. Note that if gridargs.dat is empty, or contains only
-# whitespace, the resulting gridargs array will be empty -- zero entries --
-# therefore "${gridargs[@]}" entirely vanishes from the command line below,
-# just as we want.
-if ! $skip_gridargs ; then
-    eval gridargs=("$(<etc/gridargs.dat)")
-fi
-
 # Run the program.
 # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the
-# command line. But DO quote "$@": preserve separate args as individually
-# quoted. Similar remarks about the contents of gridargs.
-$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"
+# command line. But DO quote "${ARGS[@]}": preserve separate args as
+# individually quoted.
+$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}"
 LL_RUN_ERR=$?
 
 # Handle any resulting errors
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3e94c5edf758ade2e383e3f2bf00aea8ddfbb541..f4ce3c9118c216d9c6c5de7c2ad97e99ac3dceb8 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -46,6 +46,7 @@
 #include "llenvmanager.h"
 #include "llfirstuse.h"
 #include "llfloatercamera.h"
+#include "llfloaterimcontainer.h"
 #include "llfloaterreg.h"
 #include "llfloatertools.h"
 #include "llgroupactions.h"
@@ -91,6 +92,7 @@
 #include "llworld.h"
 #include "llworldmap.h"
 #include "stringize.h"
+#include "boost/foreach.hpp"
 
 using namespace LLAvatarAppearanceDefines;
 
@@ -433,7 +435,7 @@ void LLAgent::init()
 {
 	mMoveTimer.start();
 
-	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
+	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", LLControlVariable::PERSIST_NO);
 	gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
 	
 	// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
@@ -2037,7 +2039,16 @@ void LLAgent::endAnimationUpdateUI()
 			{
 				skip_list.insert(LLFloaterReg::findInstance("mini_map"));
 			}
-		
+
+			LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+			LLFloaterIMContainer::floater_list_t conversations;
+			im_box->getDetachedConversationFloaters(conversations);
+			BOOST_FOREACH(LLFloater* conversation, conversations)
+			{
+				llinfos << "skip_list.insert(session_floater): " << conversation->getTitle() << llendl;
+				skip_list.insert(conversation);
+			}
+
 			gFloaterView->popVisibleAll(skip_list);
 #endif
 			mViewsPushed = FALSE;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ffb168b43b53948c92c6d0cb87439c4bb937f9ed..003d82dd0e7d374989dfde840eeeb3547b9da119 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -668,7 +668,6 @@ LLAppViewer::LLAppViewer() :
 	mSecondInstance(false),
 	mSavedFinalSnapshot(false),
 	mSavePerAccountSettings(false),		// don't save settings on logout unless login succeeded.
-	mForceGraphicsDetail(false),
 	mQuitRequested(false),
 	mLogoutRequestSent(false),
 	mYieldTime(-1),
@@ -2307,17 +2306,24 @@ void LLAppViewer::loadColorSettings()
 	LLUIColorTable::instance().loadFromSettings();
 }
 
+namespace
+{
+    void handleCommandLineError(LLControlGroupCLP& clp)
+    {
+		llwarns << "Error parsing command line options. Command Line options ignored."  << llendl;
+
+		llinfos << "Command line usage:\n" << clp << llendl;
+
+		OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()),
+					 LLStringUtil::null,
+					 OSMB_OK);
+    }
+} // anonymous namespace
+
 bool LLAppViewer::initConfiguration()
 {	
 	//Load settings files list
 	std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
-	//LLControlGroup settings_control("SettingsFiles");
-	//llinfos << "Loading settings file list " << settings_file_list << llendl;
-	//if (0 == settings_control.loadFromFile(settings_file_list))
-	//{
- //       llerrs << "Cannot load default configuration file " << settings_file_list << llendl;
-	//}
-
 	LLXMLNodePtr root;
 	BOOL success  = LLXMLNode::parseFile(settings_file_list, root, NULL);
 	if (!success)
@@ -2376,9 +2382,7 @@ bool LLAppViewer::initConfiguration()
 	{
 		c->setValue(true, false);
 	}
-#endif
 
-#ifndef	LL_RELEASE_FOR_DOWNLOAD
 	gSavedSettings.setBOOL("QAMode", TRUE );
 	gSavedSettings.setS32("WatchdogEnabled", 0);
 #endif
@@ -2414,13 +2418,7 @@ bool LLAppViewer::initConfiguration()
 
 	if(!initParseCommandLine(clp))
 	{
-		llwarns	<< "Error parsing command line options.	Command	Line options ignored."  << llendl;
-		
-		llinfos	<< "Command	line usage:\n" << clp << llendl;
-
-		std::ostringstream msg;
-		msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage();
-		OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+		handleCommandLineError(clp);
 		return false;
 	}
 	
@@ -2467,12 +2465,16 @@ bool LLAppViewer::initConfiguration()
 	loadSettingsFromDirectory("UserSession");
 
 	// - apply command line settings 
-	clp.notify(); 
+	if (! clp.notify())
+	{
+		handleCommandLineError(clp);
+		return false;
+	}
 
 	// Register the core crash option as soon as we can
 	// if we want gdb post-mortem on cores we need to be up and running
 	// ASAP or we might miss init issue etc.
-	if(clp.hasOption("disablecrashlogger"))
+	if(gSavedSettings.getBOOL("DisableCrashLogger"))
 	{
 		llwarns << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << llendl;
 		LLAppViewer::instance()->disableCrashlogger();
@@ -2545,91 +2547,52 @@ bool LLAppViewer::initConfiguration()
         }
     }
 
-    if(clp.hasOption("channel"))
-    {
-		LLVersionInfo::resetChannel(clp.getOption("channel")[0]);
+	std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
+	if(! CmdLineChannel.empty())
+	{
+		LLVersionInfo::resetChannel(CmdLineChannel);
 	}
 
 	// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
-	if(clp.hasOption("crashonstartup"))
-	{
-		gCrashOnStartup = TRUE;
-	}
+	gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup");
 
-	if (clp.hasOption("logperformance"))
+	if (gSavedSettings.getBOOL("LogPerformance"))
 	{
 		LLFastTimer::sLog = TRUE;
 		LLFastTimer::sLogName = std::string("performance");		
 	}
-	
-	if (clp.hasOption("logmetrics"))
- 	{
- 		LLFastTimer::sMetricLog = TRUE ;
-		// '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test
-		// In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...)
-		std::string test_name = clp.getOption("logmetrics")[0];
+
+	std::string test_name(gSavedSettings.getString("LogMetrics"));
+	if (! test_name.empty())
+	{
+		LLFastTimer::sMetricLog = TRUE ;
+		// '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
+		// In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
 		llinfos << "'--logmetrics' argument : " << test_name << llendl;
-		if (test_name == "")
-		{
-			llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl;
-			LLFastTimer::sLogName = DEFAULT_METRIC_NAME;
-		}
-		else
-		{
-			LLFastTimer::sLogName = test_name;
-		}
+		LLFastTimer::sLogName = test_name;
  	}
 
 	if (clp.hasOption("graphicslevel"))
 	{
-		const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel");
-        if(value.size() != 1)
-        {
-			llwarns << "Usage: -graphicslevel <0-3>" << llendl;
-        }
-        else
-        {
-			std::string detail = value.front();
-			mForceGraphicsDetail = TRUE;
-			
-			switch (detail.c_str()[0])
-			{
-				case '0': 
-					gSavedSettings.setU32("RenderQualityPerformance", 0);		
-					break;
-				case '1': 
-					gSavedSettings.setU32("RenderQualityPerformance", 1);		
-					break;
-				case '2': 
-					gSavedSettings.setU32("RenderQualityPerformance", 2);		
-					break;
-				case '3': 
-					gSavedSettings.setU32("RenderQualityPerformance", 3);		
-					break;
-				default:
-					mForceGraphicsDetail = FALSE;
-					llwarns << "Usage: -graphicslevel <0-3>" << llendl;
-					break;
-			}
-        }
-	}
-
-	if (clp.hasOption("analyzeperformance"))
-	{
-		LLFastTimerView::sAnalyzePerformance = TRUE;
+		// User explicitly requested --graphicslevel on the command line. We
+		// expect this switch has already set RenderQualityPerformance. Check
+		// that value for validity.
+		U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
+		if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
+		{
+			// graphicslevel is valid: save it and engage it later. Capture
+			// the requested value separately from the settings variable
+			// because, if this is the first run, LLViewerWindow's constructor
+			// will call LLFeatureManager::applyRecommendedSettings(), which
+			// overwrites this settings variable!
+			mForceGraphicsLevel = graphicslevel;
+		}
 	}
 
-	if (clp.hasOption("replaysession"))
-	{
-		gAgentPilot.setReplaySession(TRUE);
-	}
+	LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
+	gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession"));
 
-	if (clp.hasOption("nonotifications"))
-	{
-		gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false);
-	}
-	
-	if (clp.hasOption("debugsession"))
+	if (gSavedSettings.getBOOL("DebugSession"))
 	{
 		gDebugSession = TRUE;
 		gDebugGL = TRUE;
@@ -2654,20 +2617,16 @@ bool LLAppViewer::initConfiguration()
     // What can happen is that someone can use IE (or potentially 
     // other browsers) and do the rough equivalent of command 
     // injection and steal passwords. Phoenix. SL-55321
-    if(clp.hasOption("url"))
-    {
-		LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
-		if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION) 
-		{  
-			LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid());
-			
-		}  
-    }
-    else if(clp.hasOption("slurl"))
-    {
-		LLSLURL start_slurl(clp.getOption("slurl")[0]);
+	std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation"));
+	if(! CmdLineLoginLocation.empty())
+	{
+		LLSLURL start_slurl(CmdLineLoginLocation);
 		LLStartUp::setStartSLURL(start_slurl);
-    }
+		if(start_slurl.getType() == LLSLURL::LOCATION) 
+		{  
+			LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
+		}
+	}
 
 	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
 	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
@@ -2810,9 +2769,8 @@ bool LLAppViewer::initConfiguration()
 		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
 		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
 	}
-	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
-			 && !clp.hasOption("url")
-			 && !clp.hasOption("slurl"))
+	else if ((clp.hasOption("login") || clp.hasOption("autologin"))
+			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
 	{
 		// If automatic login from command line with --login switch
 		// init StartSLURL location.
@@ -3048,13 +3006,19 @@ namespace {
 void LLAppViewer::initUpdater()
 {
 	// Initialize the updater service.
-	// Generate URL to the udpater service
 	// Get Channel
 	// Get Version
-	std::string url = gSavedSettings.getString("UpdaterServiceURL");
+
+	/*****************************************************************
+	 * Previously, the url was derived from the settings 
+	 *    UpdaterServiceURL
+	 *    UpdaterServicePath
+	 * it is now obtained from the grid manager.  The settings above
+	 * are no longer used.
+	 *****************************************************************/
 	std::string channel = LLVersionInfo::getChannel();
 	std::string version = LLVersionInfo::getVersion();
-	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
+
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 	bool willing_to_test;
 	LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL;
@@ -3079,9 +3043,7 @@ void LLAppViewer::initUpdater()
 	}
 
 	mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
-	mUpdater->initialize(url, 
-						 service_path, 
-						 channel, 
+	mUpdater->initialize(channel, 
 						 version,
 						 gPlatform,
 						 getOSInfo().getOSVersionString(),
@@ -3186,11 +3148,12 @@ bool LLAppViewer::initWindow()
 	// Initialize GL stuff
 	//
 
-	if (mForceGraphicsDetail)
+	if (mForceGraphicsLevel)
 	{
-		LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
+		LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
+		gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
 	}
-			
+
 	// Set this flag in case we crash while initializing GL
 	gSavedSettings.setBOOL("RenderInitError", TRUE);
 	gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index cd91ae8b2bc9c3ba76b67418270af5c6d939790d..3af360b52991b3bcf53c9412e951f05b4da4cf6f 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -32,6 +32,7 @@
 #include "llsys.h"			// for LLOSInfo
 #include "lltimer.h"
 #include "llappcorehttp.h"
+#include <boost/optional.hpp>
 
 class LLCommandLineParser;
 class LLFrameTimer;
@@ -258,7 +259,7 @@ private:
 	bool mSavedFinalSnapshot;
 	bool mSavePerAccountSettings;		// only save per account settings if login succeeded
 
-	bool mForceGraphicsDetail;
+	boost::optional<U32> mForceGraphicsLevel;
 
     bool mQuitRequested;				// User wants to quit, may have modified documents open.
     bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim.
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 4d340cafa9dfed9769b5a56382e32886a611fd35..c7b437598c2d55c7f90b3ee50ea641898a97c6ff 100755
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -148,28 +148,13 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp)
 	// The next two lines add the support for parsing the mac -psn_XXX arg.
 	clp.addOptionDesc("psn", NULL, 1, "MacOSX process serial number");
 	clp.setCustomParser(parse_psn);
-	
-    // First read in the args from arguments txt.
-    const char* filename = "arguments.txt";
-	llifstream ifs(filename, llifstream::binary);
-	if (!ifs.is_open())
-	{
-		llwarns << "Unable to open file" << filename << llendl;
-		return false;
-	}
-	
-	if(clp.parseCommandLineFile(ifs) == false)
-	{
-		return false;
-	}
 
-	// Then parse the user's command line, so that any --url arg can appear last
-	// Succesive calls to clp.parse... will NOT override earlier options. 
+	// parse the user's command line
 	if(clp.parseCommandLine(gArgC, gArgV) == false)
 	{
 		return false;
 	}
-    	
+
 	// Get the user's preferred language string based on the Mac OS localization mechanism.
 	// To add a new localization:
 		// go to the "Resources" section of the project
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 43757d0174f96309596896189a7ee027e00291f8..8b2d9e639fefb429507f6bbf345ea6f2fd5a21af 100755
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -139,8 +139,6 @@ void LLChannelManager::onLoginCompleted()
 	}
 
 	LLPersistentNotificationStorage::getInstance()->loadNotifications();
-
-	LLDoNotDisturbNotificationStorage::getInstance()->initialize();
 	LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
 }
 
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 7d0331757bed74a6c3887127f417d104d105d47d..b3bc0ba966dca4760715f539dd433572a80afafd 100755
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -381,7 +381,7 @@ void LLChatBar::sendChat( EChatType type )
 			if (!utf8_revised_text.empty())
 			{
 				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
+				sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim"));
 			}
 		}
 	}
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 0f138873ac8cec543dbc16078ef48098af611934..af3c6eff1169323a9dfe93d24aee41849024d6e4 100755
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -628,6 +628,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	editor_params.enabled = false; // read only
 	editor_params.show_context_menu = "true";
 	mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
+	mEditor->setIsFriendCallback(LLAvatarActions::isFriend);
 }
 
 LLSD LLChatHistory::getValue() const
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index a1a9463d4363cd695f09badce3bd4b6fef7feaf0..fd4f17b69439ab3321af1c0626c7e5d60d570340 100755
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -323,12 +323,11 @@ BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 			return TRUE;
 		else
 		{
-			(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
+			LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory();
 			return FALSE;
 		}
 	}
-
-	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
+	LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory();
 	return LLPanel::handleMouseUp(x,y,mask);
 }
 
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 17d403bbe1040b492658123af45a8e606e99037a..a6384ded1251b67fc48578b3c5978de0553c6352 100755
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -38,16 +38,23 @@
 #endif
 
 #include <boost/program_options.hpp>
+#include <boost/lexical_cast.hpp>
 #include <boost/bind.hpp>
-#include<boost/tokenizer.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/assign/list_of.hpp>
 
 #if _MSC_VER
 #   pragma warning(pop)
 #endif
 
 #include "llsdserialize.h"
+#include "llerror.h"
+#include "stringize.h"
+#include <string>
+#include <set>
 #include <iostream>
 #include <sstream>
+#include <typeinfo>
 
 #include "llcontrol.h"
 
@@ -63,10 +70,22 @@ namespace po = boost::program_options;
 // This could be good or bad, and probably won't matter for most use cases.
 namespace 
 {
+    // List of command-line switches that can't map-to settings variables.
+    // Going forward, we want every new command-line switch to map-to some
+    // settings variable. This list is used to validate that.
+    const std::set<std::string> unmapped_options = boost::assign::list_of
+        ("help")
+        ("set")
+        ("setdefault")
+        ("settings")
+        ("sessionsettings")
+        ("usersessionsettings")
+    ;
+
     po::options_description gOptionsDesc;
     po::positional_options_description gPositionalOptions;
 	po::variables_map gVariableMap;
-    
+
     const LLCommandLineParser::token_vector_t gEmptyValue;
 
     void read_file_into_string(std::string& str, const std::basic_istream < char >& file)
@@ -384,9 +403,19 @@ bool LLCommandLineParser::parseCommandLineFile(const std::basic_istream < char >
     return parseCommandLineString(args);
 }
 
-void LLCommandLineParser::notify()
+bool LLCommandLineParser::notify()
 {
-    po::notify(gVariableMap);    
+    try
+    {
+        po::notify(gVariableMap);
+        return true;
+    }
+    catch (const LLCLPError& e)
+    {
+        llwarns << "Caught Error: " << e.what() << llendl;
+        mErrorMsg = e.what();
+        return false;
+    }
 }
 
 void LLCommandLineParser::printOptions() const
@@ -428,43 +457,129 @@ const LLCommandLineParser::token_vector_t& LLCommandLineParser::getOption(const
 //----------------------------------------------------------------------------
 // LLControlGroupCLP defintions
 //----------------------------------------------------------------------------
+namespace {
+LLCommandLineParser::token_vector_t::value_type
+onevalue(const std::string& option,
+         const LLCommandLineParser::token_vector_t& value)
+{
+    if (value.empty())
+    {
+        // What does it mean when the user specifies a command-line switch
+        // that requires a value, but omits the value? Complain.
+        throw LLCLPError(STRINGIZE("No value specified for --" << option << "!"));
+    }
+    else if (value.size() > 1)
+    {
+        llwarns << "Ignoring extra tokens specified for --"
+                << option << "." << llendl; 
+    }
+    return value[0];
+}
+
+void badvalue(const std::string& option,
+              const std::string& varname,
+              const std::string& type,
+              const std::string& value)
+{
+    // If the user passes an unusable value for a command-line switch, it
+    // seems like a really bad idea to just ignore it, even with a log
+    // warning.
+    throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option
+                               << "' for variable '" << varname << "' of type " << type
+                               << ": '" << value << "'"));
+}
+
+template <typename T>
+T convertTo(const std::string& option,
+            const std::string& varname,
+            const LLCommandLineParser::token_vector_t::value_type& value)
+{
+    try
+    {
+        return boost::lexical_cast<T>(value);
+    }
+    catch (const boost::bad_lexical_cast&)
+    {
+        badvalue(option, varname, typeid(T).name(), value);
+        // bogus return; compiler unaware that badvalue() won't return
+        return T();
+    }
+}
+
 void setControlValueCB(const LLCommandLineParser::token_vector_t& value, 
-                       const std::string& opt_name, 
-                       LLControlGroup* ctrlGroup)
+                       const std::string& option, 
+                       LLControlVariable* ctrl)
 {
-    // *FIX: Do sematic conversion here.
+    // *FIX: Do semantic conversion here.
     // LLSD (ImplString) Is no good for doing string to type conversion for...
     // booleans
     // compound types
     // ?...
 
-    LLControlVariable* ctrl = ctrlGroup->getControl(opt_name);
     if(NULL != ctrl)
     {
         switch(ctrl->type())
         {
         case TYPE_BOOLEAN:
-            if(value.size() > 1)
+            if (value.empty())
             {
-                llwarns << "Ignoring extra tokens." << llendl; 
+                // Boolean-valued command-line switches are unusual. If you
+                // simply specify the switch without an explicit value, we can
+                // infer you mean 'true'.
+                ctrl->setValue(LLSD(true), false);
             }
-              
-            if(value.size() > 0)
+            else
             {
+                // Only call onevalue() AFTER handling value.empty() case!
+                std::string token(onevalue(option, value));
+            
                 // There's a token. check the string for true/false/1/0 etc.
                 BOOL result = false;
-                BOOL gotSet = LLStringUtil::convertToBOOL(value[0], result);
-                if(gotSet)
+                BOOL gotSet = LLStringUtil::convertToBOOL(token, result);
+                if (gotSet)
                 {
                     ctrl->setValue(LLSD(result), false);
                 }
+                else
+                {
+                    badvalue(option, ctrl->getName(), "bool", token);
+                }
+            }
+            break;
+
+        case TYPE_U32:
+        {
+            std::string token(onevalue(option, value));
+            // To my surprise, for an unsigned target, lexical_cast() doesn't
+            // complain about an input string such as "-17". In that case, you
+            // get a very large positive result. So for U32, make sure there's
+            // no minus sign!
+            if (token.find('-') == std::string::npos)
+            {
+                ctrl->setValue(LLSD::Integer(convertTo<U32>(option, ctrl->getName(), token)),
+                               false);
             }
             else
             {
-                ctrl->setValue(LLSD(true), false);
+                badvalue(option, ctrl->getName(), "unsigned", token);
             }
             break;
+        }
+
+        case TYPE_S32:
+            ctrl->setValue(convertTo<S32>(option, ctrl->getName(),
+                                          onevalue(option, value)), false);
+            break;
+
+        case TYPE_F32:
+            ctrl->setValue(convertTo<F32>(option, ctrl->getName(),
+                                          onevalue(option, value)), false);
+            break;
 
+        // It appears that no one has yet tried to define a command-line
+        // switch mapped to a settings variable of TYPE_VEC3, TYPE_VEC3D,
+        // TYPE_RECT, TYPE_COL4, TYPE_COL3. Such types would certainly seem to
+        // call for a bit of special handling here...
         default:
             {
                 // For the default types, let llsd do the conversion.
@@ -481,16 +596,9 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
 
                     ctrl->setValue(llsdArray, false);
                 }
-                else if(value.size() > 0)
+                else
                 {
-					if(value.size() > 1)
-					{
-						llwarns << "Ignoring extra tokens mapped to the setting: " << opt_name << "." << llendl; 
-					}
-
-                    LLSD llsdValue;
-                    llsdValue.assign(LLSD::String(value[0]));
-                    ctrl->setValue(llsdValue, false);
+                    ctrl->setValue(onevalue(option, value), false);
                 }
             }
             break;
@@ -498,12 +606,14 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
     }
     else
     {
-        llwarns << "Command Line option mapping '" 
-            << opt_name 
-            << "' not found! Ignoring." 
-            << llendl;
+        // This isn't anything a user can affect -- it's a misconfiguration on
+        // the part of the coder. Rub the coder's nose in the problem right
+        // away so even preliminary testing will surface it.
+        llerrs << "Command Line option --" << option
+               << " maps to unknown setting!" << llendl;
     }
 }
+} // anonymous namespace
 
 void LLControlGroupCLP::configure(const std::string& config_filename, LLControlGroup* controlGroup)
 {
@@ -561,11 +671,37 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG
             }
 
             boost::function1<void, const token_vector_t&> callback;
-            if(option_params.has("map-to") && (NULL != controlGroup))
+            if (! option_params.has("map-to"))
+            {
+                // If this option isn't mapped to a settings variable, is it
+                // one of the ones for which that's unreasonable, or did
+                // someone carelessly add a new option? (Make all these
+                // configuration errors fatal so a maintainer will catch them
+                // right away.)
+                std::set<std::string>::const_iterator found = unmapped_options.find(long_name);
+                if (found == unmapped_options.end())
+                {
+                    llerrs << "New command-line option " << long_name
+                           << " should map-to a variable in settings.xml" << llendl;
+                }
+            }
+            else                    // option specifies map-to
             {
                 std::string controlName = option_params["map-to"].asString();
-                callback = boost::bind(setControlValueCB, _1, 
-                                       controlName, controlGroup);
+                if (! controlGroup)
+                {
+                    llerrs << "Must pass gSavedSettings to LLControlGroupCLP::configure() for "
+                           << long_name << " (map-to " << controlName << ")" << llendl;
+                }
+
+                LLControlVariable* ctrl = controlGroup->getControl(controlName);
+                if (! ctrl)
+                {
+                    llerrs << "Option " << long_name << " specifies map-to " << controlName
+                           << " which does not exist" << llendl;
+                }
+
+                callback = boost::bind(setControlValueCB, _1, long_name, ctrl);
             }
 
             this->addOptionDesc(
diff --git a/indra/newview/llcommandlineparser.h b/indra/newview/llcommandlineparser.h
index 44f2a268431edbb64917cc4f12217b7e7b3c113e..71388b8217ec700d3cb711475f96bb2bc0a054ab 100755
--- a/indra/newview/llcommandlineparser.h
+++ b/indra/newview/llcommandlineparser.h
@@ -86,7 +86,7 @@ public:
 	 * 
 	 * Use this to handle the results of parsing. 
 	 */
-	void notify();
+	bool notify();
 	
 	/** @brief Print a description of the configured options.
 	 *
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index c74ce24872f87d9125f7720f7f015cba4ac6c31b..192a594c9dfae0e5da55269df1902fd7bb980191 100755
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -363,7 +363,10 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
     lldebugs << "LLConversationItemParticipant::buildContextMenu()" << llendl;
     menuentry_vec_t items;
     menuentry_vec_t disabled_items;
-
+    if((flags & ITEM_IN_MULTI_SELECTION) && (this->getType() != CONV_SESSION_NEARBY))
+    {
+    	items.push_back(std::string("close_selected_conversations"));
+    }
     if(this->getType() == CONV_SESSION_1_ON_1)
     {
         items.push_back(std::string("close_conversation"));
@@ -386,6 +389,10 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
         addVoiceOptions(items);
         items.push_back(std::string("chat_history"));
     }
+    else if(this->getType() == CONV_SESSION_NEARBY)
+    {
+        items.push_back(std::string("chat_history"));
+    }
 
     hide_context_entries(menu, items, disabled_items);
 }
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 876658504946906aaa1b10747111b26672a85377..d8cdcdfc97f1bdef4c7cca48cdd8cd15f05574ff 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -252,11 +252,10 @@ public:
 	const std::string& 	getName() const { return mEmpty; }
 	const std::string& 	getFilterText() { return mEmpty; }
 	void 				setModified(EFilterModified behavior = FILTER_RESTART) { }
-		
-	void 				setFilterCount(S32 count) { }
-	S32 				getFilterCount() const { return 0; }
-	void 				decrementFilterCount() { }
-		
+
+  	void 				resetTime(S32 timeout) { }
+    bool                isTimedOut() { return false; }
+   
 	bool 				isDefault() const { return true; }
 	bool 				isNotDefault() const { return false; }
 	void 				markDefault() { }
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index b6c53e5e30f6dae92d95857597dd2826003850d9..9faa12b2eeade59bba5d8d7797d4c19b318804bb 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -118,9 +118,19 @@ void LLConversationViewSession::setFlashState(bool flash_state)
 	mFlashTimer->stopFlashing();
 }
 
+void LLConversationViewSession::setHighlightState(bool hihglight_state)
+{
+	mFlashStateOn = hihglight_state;
+	mFlashStarted = true;
+	mFlashTimer->stopFlashing();
+}
+
 void LLConversationViewSession::startFlashing()
 {
-	if (isInVisibleChain() && mFlashStateOn && !mFlashStarted)
+	LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+
+	// Need to start flashing only when "Conversations" is opened or brought on top
+	if (isInVisibleChain() && !im_box->isMinimized() && mFlashStateOn && !mFlashStarted)
 	{
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
@@ -263,6 +273,29 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 	return result;
 }
 
+BOOL LLConversationViewSession::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+	BOOL result = LLFolderViewFolder::handleMouseUp(x, y, mask);
+
+	LLFloater* volume_floater = LLFloaterReg::findInstance("floater_voice_volume");
+	LLFloater* chat_volume_floater = LLFloaterReg::findInstance("chat_voice");
+	if (result 
+		&& getRoot()
+		&& !(volume_floater && volume_floater->isShown() && volume_floater->hasFocus())
+		&& !(chat_volume_floater && chat_volume_floater->isShown() && chat_volume_floater->hasFocus()))
+	{
+		LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+		LLUUID session_id = item? item->getUUID() : LLUUID();
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+		if(!session_floater->hasFocus())
+		{
+			session_floater->setFocus(true);
+		}
+    }
+
+	return result;
+}
+
 BOOL LLConversationViewSession::handleRightMouseDown( S32 x, S32 y, MASK mask )
 {
     BOOL result = LLFolderViewFolder::handleRightMouseDown(x, y, mask);
@@ -340,16 +373,20 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 {
 	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
 	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
-	LLFolderViewModelItem* item = mViewModelItem;
-	LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID();
-	LLFloater* session_floater = LLFloaterIMSessionTab::getConversation(session_uuid);
-	
-	if (session_floater && !session_floater->getHost() && !session_floater->isMinimized())
+	LLFloater* session_floater = getSessionFloater();
+	if (session_floater && session_floater->isDetachedAndNotMinimized())
 	{
 		session_floater->setVisible(visible);
 	}
 }
 
+LLFloater* LLConversationViewSession::getSessionFloater()
+{
+	LLFolderViewModelItem* item = mViewModelItem;
+	LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID();
+	return LLFloaterIMSessionTab::getConversation(session_uuid);
+}
+
 LLConversationViewParticipant* LLConversationViewSession::findParticipant(const LLUUID& participant_id)
 {
 	// This is *not* a general tree parsing algorithm. We search only in the mItems list
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 3eb2e63792d00e8fe5bf9d977488ea5818f347d9..5a74974302678e5978472ad74a926b00743a83ee 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -69,6 +69,7 @@ public:
 	/*virtual*/ void draw();
 	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask );
 
 	/*virtual*/ S32 arrange(S32* width, S32* height);
 
@@ -86,6 +87,9 @@ public:
 	virtual void refresh();
 
 	/*virtual*/ void setFlashState(bool flash_state);
+	void setHighlightState(bool hihglight_state);
+
+	LLFloater* getSessionFloater();
 
 private:
 
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 82affcf06885211ab1385ce084de6a73333ebe0e..495cd01349fa27f9aaa4a0bac82f918568840ad9 100755
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -70,7 +70,7 @@ BOOL LLDoNotDisturbNotificationStorageTimer::tick()
 
 LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
 	: LLSingleton<LLDoNotDisturbNotificationStorage>()
-	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+	, LLNotificationStorage("")
     , mDirty(false)
 {
     nameToPayloadParameterMap[toastName] = "SESSION_ID";
@@ -83,6 +83,7 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
 
 void LLDoNotDisturbNotificationStorage::initialize()
 {
+	setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
 	getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
 }
 
@@ -115,7 +116,8 @@ void LLDoNotDisturbNotificationStorage::saveNotifications()
 	{
 		LLNotificationPtr notificationPtr = historyIter->second;
 
-		if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired())
+		if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() &&
+			!notificationPtr->isExpired() && !notificationPtr->isPersistent())
 		{
 			data.append(notificationPtr->asLLSD(true));
 		}
@@ -210,12 +212,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 
 	}
 
-    if(imToastExists)
-    {
-        LLFloaterReg::showInstance("im_container");
-    }
-
-	if(group_ad_hoc_toast_exists)
+    bool isConversationLoggingAllowed = gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
+	if(group_ad_hoc_toast_exists && isConversationLoggingAllowed)
 	{
 		LLFloaterReg::showInstance("conversation");
 	}
@@ -266,11 +264,6 @@ void LLDoNotDisturbNotificationStorage::updateNotifications()
         }
     }
 
-    if(imToastExists)
-    {   
-        LLFloaterReg::showInstance("im_container");
-    }
-
     if(imToastExists || offerExists)
     {
         make_ui_sound("UISndNewIncomingIMSession");
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 6d90667194fd3a8bb3ad7ca9508fe9495e3a1501..b35ef3a961748205f9051b7535eb74e30c9988c2 100755
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -400,6 +400,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
 	addChild(mMoreTextBox);
 
+	mDropDownItemsCount = 0;
+
 	LLTextBox::Params label_param(p.label);
 	mBarLabel = LLUICtrlFactory::create<LLTextBox> (label_param);
 	addChild(mBarLabel);
@@ -820,11 +822,13 @@ void LLFavoritesBarCtrl::updateButtons()
 		}
 		// Update overflow menu
 		LLToggleableMenu* overflow_menu = static_cast <LLToggleableMenu*> (mOverflowMenuHandle.get());
-		if (overflow_menu && overflow_menu->getVisible())
+		if (overflow_menu && overflow_menu->getVisible() && (overflow_menu->getItemCount() != mDropDownItemsCount))
 		{
 			overflow_menu->setVisible(FALSE);
 			if (mUpdateDropDownItems)
+			{
 				showDropDownMenu();
+			}
 		}
 	}
 	else
@@ -940,6 +944,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 		menu->updateParent(LLMenuGL::sMenuContainer);
 		menu->setButtonRect(mMoreTextBox->getRect(), this);
 		positionAndShowMenu(menu);
+		mDropDownItemsCount = menu->getItemCount();
 	}
 }
 
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index f06e9b9b6459c18766d6605d26644a3b098d7dba..211d3c4ce35cd860a4fbdc236a39a9f4af9fb4c9 100755
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -101,6 +101,7 @@ protected:
 	LLUUID mFavoriteFolderId;
 	const LLFontGL *mFont;
 	S32 mFirstDropDownItem;
+	S32 mDropDownItemsCount;
 	bool mUpdateDropDownItems;
 	bool mRestoreOverflowMenu;
 
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ddb9d3bc4369ab4d03c2dcbd41884776158e5488..9d292ce7bb7a7f3fe6f66642715bcc0c4e9b3dad 100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -30,6 +30,7 @@
 #include <fstream>
 
 #include <boost/regex.hpp>
+#include <boost/assign/list_of.hpp>
 
 #include "llfeaturemanager.h"
 #include "lldir.h"
@@ -52,6 +53,8 @@
 #include "llboost.h"
 #include "llweb.h"
 #include "llviewershadermgr.h"
+#include "llstring.h"
+#include "stringize.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -187,6 +190,55 @@ void LLFeatureList::dump()
 	LL_DEBUGS("RenderInit") << LL_ENDL;
 }
 
+static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of
+	("Low")
+	("LowMid")
+	("Mid")
+	("MidHigh")
+	("High")
+	("HighUltra")
+	("Ultra")
+;
+
+U32 LLFeatureManager::getMaxGraphicsLevel() const
+{
+	return sGraphicsLevelNames.size() - 1;
+}
+
+bool LLFeatureManager::isValidGraphicsLevel(U32 level) const
+{
+	return (level <= getMaxGraphicsLevel());
+}
+
+std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const
+{
+	if (isValidGraphicsLevel(level))
+	{
+		return sGraphicsLevelNames[level];
+	}
+	return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. "
+					 << getMaxGraphicsLevel());
+}
+
+S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const
+{
+	const std::string FixedFunction("FixedFunction");
+	std::string rname(name);
+	if (LLStringUtil::endsWith(rname, FixedFunction))
+	{
+		// chop off any "FixedFunction" suffix
+		rname = rname.substr(0, rname.length() - FixedFunction.length());
+	}
+	for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i)
+	{
+		if (sGraphicsLevelNames[i] == rname)
+		{
+			return i;
+		}
+	}
+	return -1;
+}
+
 LLFeatureList *LLFeatureManager::findMask(const std::string& name)
 {
 	if (mMaskList.count(name))
@@ -620,7 +672,7 @@ void LLFeatureManager::applyRecommendedSettings()
 {
 	// apply saved settings
 	// cap the level at 2 (high)
-	S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
+	U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
 
 	llinfos << "Applying Recommended Features" << llendl;
 
@@ -696,62 +748,33 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
 	}
 }
 
-void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
+void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
 {
 	LLViewerShaderMgr::sSkipReload = true;
 
 	applyBaseMasks();
-	
-	switch (level)
+
+	// if we're passed an invalid level, default to "Low"
+	std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
+	if (features == "Low")
 	{
-		case 0:
 #if LL_DARWIN
-			// This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
-			// systems which support them instead of falling back to fixed-function unnecessarily
-			// MAINT-2157
-			//
-			if (gGLManager.mGLVersion < 2.1f)
-			{
-				maskFeatures("LowFixedFunction");			
-			}
-			else
-			{ //same as low, but with "Basic Shaders" enabled
-				maskFeatures("Low");
-			}
+		// This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
+		// systems which support them instead of falling back to fixed-function unnecessarily
+		// MAINT-2157
+		if (gGLManager.mGLVersion < 2.1f)
 #else
-			if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
-			{ //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
-				maskFeatures("LowFixedFunction");			
-			}
-			else
-			{ //same as low, but with "Basic Shaders" enabled
-				maskFeatures("Low");
-			}
+		// only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+		if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
 #endif
-			break;
-		case 1:
-			maskFeatures("LowMid");
-			break;
-		case 2:
-			maskFeatures("Mid");
-			break;
-		case 3:
-			maskFeatures("MidHigh");
-			break;
-		case 4:
-			maskFeatures("High");
-			break;
-		case 5:
-			maskFeatures("HighUltra");
-			break;
-		case 6:
-			maskFeatures("Ultra");
-			break;
-		default:
-			maskFeatures("Low");
-			break;
+		{
+            // same as Low, but with "Basic Shaders" disabled
+			features = "LowFixedFunction";
+		}
 	}
 
+	maskFeatures(features);
+
 	applyFeatures(skipFeatures);
 
 	LLViewerShaderMgr::sSkipReload = false;
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index ad72c167432e838d6adeb55ac0701efb5905e57d..3b8d2512362b298c8b4a57c3ee0a8a236b5cb598 100755
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -134,8 +134,18 @@ public:
 	// skipFeatures forces skipping of mostly hardware settings
 	// that we don't want to change when we change graphics
 	// settings
-	void setGraphicsLevel(S32 level, bool skipFeatures);
-	
+	void setGraphicsLevel(U32 level, bool skipFeatures);
+
+	// What 'level' values are valid to pass to setGraphicsLevel()?
+	// 0 is the low end...
+	U32 getMaxGraphicsLevel() const;
+	bool isValidGraphicsLevel(U32 level) const;
+
+	// setGraphicsLevel() levels have names.
+	std::string getNameForGraphicsLevel(U32 level) const;
+	// returns -1 for unrecognized name (hence S32 rather than U32)
+	S32 getGraphicsLevelForName(const std::string& name) const;
+
 	void applyBaseMasks();
 	void applyRecommendedSettings();
 
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 83fb887d81b3e2ad2c19fa193886d19e7ba3aa3e..fea8e34729e131acea20aa70213df227e135592a 100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -33,8 +33,10 @@
 
 // Viewer includes
 #include "llagent.h"
+#include "llagentui.h"
 #include "llappviewer.h" 
 #include "llsecondlifeurls.h"
+#include "llslurl.h"
 #include "llvoiceclient.h"
 #include "lluictrlfactory.h"
 #include "llviewertexteditor.h"
@@ -250,12 +252,16 @@ LLSD LLFloaterAbout::getInfo()
 	LLViewerRegion* region = gAgent.getRegion();
 	if (region)
 	{
-		const LLVector3d &pos = gAgent.getPositionGlobal();
+		LLVector3d pos = gAgent.getPositionGlobal();
 		info["POSITION"] = ll_sd_from_vector3d(pos);
+		info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
 		info["REGION"] = gAgent.getRegion()->getName();
 		info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
 		info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
 		info["SERVER_VERSION"] = gLastVersionChannel;
+		LLSLURL slurl;
+		LLAgentUI::buildSLURL(slurl);
+		info["SLURL"] = slurl.getSLURLString();
 	}
 
 	// CPU
@@ -307,12 +313,12 @@ LLSD LLFloaterAbout::getInfo()
 static std::string get_viewer_release_notes_url()
 {
 	// return a URL to the release notes for this viewer, such as:
-	// http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0
+	// http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
 	std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
 	if (! LLStringUtil::endsWith(url, "/"))
 		url += "/";
 	url += LLVersionInfo::getChannel() + "/";
-	url += LLVersionInfo::getShortVersion();
+	url += LLVersionInfo::getVersion();
 	return LLWeb::escapeURL(url);
 }
 
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 113aa9a8f2596c48e56f17f333a0be52e454742c..c0afb72cffb05ed6702c0c70ba374a445088be56 100755
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -513,6 +513,7 @@ void LLFloaterAvatarPicker::find()
 			url += "/";
 		}
 		url += "?page_size=100&names=";
+		std::replace(text.begin(), text.end(), '.', ' ');
 		url += LLURI::escape(text);
 		llinfos << "avatar picker " << url << llendl;
 		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString()));
@@ -748,7 +749,12 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD&
 		{
 			getChildView("ok_btn")->setEnabled(true);
 			search_results->setEnabled(true);
-			search_results->selectFirstItem();
+			search_results->sortByColumnIndex(1, TRUE);
+			std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
+			if (!search_results->selectItemByLabel(text, TRUE, 1))
+			{
+				search_results->selectFirstItem();
+			}			
 			onList();
 			search_results->setFocus(TRUE);
 		}
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index 39b6e465f3fa32e27cc608f0fe32020b4bbec5d3..76f62a7880a3c9aee0a1c42873c3f1b435fafadf 100755
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -57,6 +57,7 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
 	mDone(FALSE)
 {
 	mID.generate();
+	mCommitCallbackRegistrar.add("BulkPermission.Ok",		boost::bind(&LLFloaterBulkPermission::onOkBtn, this));
 	mCommitCallbackRegistrar.add("BulkPermission.Apply",	boost::bind(&LLFloaterBulkPermission::onApplyBtn, this));
 	mCommitCallbackRegistrar.add("BulkPermission.Close",	boost::bind(&LLFloaterBulkPermission::onCloseBtn, this));
 	mCommitCallbackRegistrar.add("BulkPermission.CheckAll",	boost::bind(&LLFloaterBulkPermission::onCheckAll, this));
@@ -66,6 +67,21 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
 
 BOOL LLFloaterBulkPermission::postBuild()
 {
+	mBulkChangeIncludeAnimations = gSavedSettings.getBOOL("BulkChangeIncludeAnimations");
+	mBulkChangeIncludeBodyParts = gSavedSettings.getBOOL("BulkChangeIncludeBodyParts");
+	mBulkChangeIncludeClothing = gSavedSettings.getBOOL("BulkChangeIncludeClothing");
+	mBulkChangeIncludeGestures = gSavedSettings.getBOOL("BulkChangeIncludeGestures");
+	mBulkChangeIncludeNotecards = gSavedSettings.getBOOL("BulkChangeIncludeNotecards");
+	mBulkChangeIncludeObjects = gSavedSettings.getBOOL("BulkChangeIncludeObjects");
+	mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts");
+	mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds");
+	mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures");
+	mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup");
+	mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy");
+	mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify");
+	mBulkChangeNextOwnerCopy = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy");
+	mBulkChangeNextOwnerTransfer = gSavedSettings.getBOOL("BulkChangeNextOwnerTransfer");
+
 	return TRUE;
 }
 
@@ -144,6 +160,12 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
 	}
 }
 
+void LLFloaterBulkPermission::onOkBtn()
+{
+	doApply();
+	closeFloater();
+}
+
 void LLFloaterBulkPermission::onApplyBtn()
 {
 	doApply();
@@ -151,6 +173,20 @@ void LLFloaterBulkPermission::onApplyBtn()
 
 void LLFloaterBulkPermission::onCloseBtn()
 {
+	gSavedSettings.setBOOL("BulkChangeIncludeAnimations", mBulkChangeIncludeAnimations);
+	gSavedSettings.setBOOL("BulkChangeIncludeBodyParts", mBulkChangeIncludeBodyParts);
+	gSavedSettings.setBOOL("BulkChangeIncludeClothing", mBulkChangeIncludeClothing);
+	gSavedSettings.setBOOL("BulkChangeIncludeGestures", mBulkChangeIncludeGestures);
+	gSavedSettings.setBOOL("BulkChangeIncludeNotecards", mBulkChangeIncludeNotecards);
+	gSavedSettings.setBOOL("BulkChangeIncludeObjects", mBulkChangeIncludeObjects);
+	gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts);
+	gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds);
+	gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures);
+	gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup);
+	gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy);
+	gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify);
+	gSavedSettings.setBOOL("BulkChangeNextOwnerCopy", mBulkChangeNextOwnerCopy);
+	gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", mBulkChangeNextOwnerTransfer);
 	closeFloater();
 }
 
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index 7dd05df7ee15e0962b648d120b689671d787d8f6..25e76eca65159c02d2a4dde3c62f8f8407c52d67 100755
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -72,6 +72,7 @@ private:
 								bool is_new);
 
 	void onCloseBtn();
+	void onOkBtn();
 	void onApplyBtn();
 	void onCommitCopy();
 	void onCheckAll() { doCheckUncheckAll(TRUE); }
@@ -94,6 +95,21 @@ private:
 	LLUUID mCurrentObjectID;
 	BOOL mDone;
 
+	bool mBulkChangeIncludeAnimations;
+	bool mBulkChangeIncludeBodyParts;
+	bool mBulkChangeIncludeClothing;
+	bool mBulkChangeIncludeGestures;
+	bool mBulkChangeIncludeNotecards;
+	bool mBulkChangeIncludeObjects;
+	bool mBulkChangeIncludeScripts;
+	bool mBulkChangeIncludeSounds;
+	bool mBulkChangeIncludeTextures;
+	bool mBulkChangeShareWithGroup;
+	bool mBulkChangeEveryoneCopy;
+	bool mBulkChangeNextOwnerModify;
+	bool mBulkChangeNextOwnerCopy;
+	bool mBulkChangeNextOwnerTransfer;
+
 	LLUUID mID;
 
 	const char* mStartString;
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index a3d715530d0a8dd48576b21d4248c69f888ac90e..b570de14aa165f2846356c8105e8309e46f5afca 100755
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -50,6 +50,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
 BOOL LLFloaterConversationPreview::postBuild()
 {
 	mChatHistory = getChild<LLChatHistory>("chat_history");
+	LLLoadHistoryThread::setLoadEndSignal(boost::bind(&LLFloaterConversationPreview::SetPages, this, _1, _2));
 
 	const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
 	std::string name;
@@ -70,7 +71,7 @@ BOOL LLFloaterConversationPreview::postBuild()
 		name = LLTrans::getString("NearbyChatTitle");
 		file = "chat";
 	}
-
+	mChatHistoryFileName = file;
 	LLStringUtil::format_map_t args;
 	args["[NAME]"] = name;
 	std::string title = getString("Title", args);
@@ -80,23 +81,46 @@ BOOL LLFloaterConversationPreview::postBuild()
 	load_params["load_all_history"] = true;
 	load_params["cut_off_todays_date"] = false;
 
-	LLLogChat::loadChatHistory(file, mMessages, load_params);
-	mCurrentPage = mMessages.size() / mPageSize;
 
+	LLSD loading;
+	loading[LL_IM_TEXT] = LLTrans::getString("loading_chat_logs");
+	mMessages.push_back(loading);
 	mPageSpinner = getChild<LLSpinCtrl>("history_page_spin");
 	mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
 	mPageSpinner->setMinValue(1);
-	mPageSpinner->setMaxValue(mCurrentPage + 1);
-	mPageSpinner->set(mCurrentPage + 1);
-
-	std::string total_page_num = llformat("/ %d", mCurrentPage + 1);
-	getChild<LLTextBox>("page_num_label")->setValue(total_page_num);
-
+	mPageSpinner->set(1);
+	mPageSpinner->setEnabled(false);
+	mChatHistoryLoaded = false;
+	LLLogChat::startChatHistoryThread(file, load_params);
 	return LLFloater::postBuild();
 }
 
+void LLFloaterConversationPreview::SetPages(std::list<LLSD>& messages, const std::string& file_name)
+{
+	if(file_name == mChatHistoryFileName)
+	{
+		mMessages = messages;
+
+
+		mCurrentPage = mMessages.size() / mPageSize;
+		mPageSpinner->setEnabled(true);
+		mPageSpinner->setMaxValue(mCurrentPage+1);
+		mPageSpinner->set(mCurrentPage+1);
+
+		std::string total_page_num = llformat("/ %d", mCurrentPage+1);
+		getChild<LLTextBox>("page_num_label")->setValue(total_page_num);
+		mChatHistoryLoaded = true;
+
+	}
+
+}
 void LLFloaterConversationPreview::draw()
 {
+	if(mChatHistoryLoaded)
+	{
+		showHistory();
+		mChatHistoryLoaded = false;
+	}
 	LLFloater::draw();
 }
 
@@ -128,6 +152,11 @@ void LLFloaterConversationPreview::showHistory()
 
 	for (int msg_num = 0; (iter != mMessages.end() && msg_num < mPageSize); ++iter, ++msg_num)
 	{
+		if (iter->size() == 0)
+		{
+			continue;
+		}
+
 		LLSD msg = *iter;
 
 		LLUUID from_id 		= LLUUID::null;
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index b17ae84b632e9fecc21a7ce5360afc2335fc484d..389f3dfd09b43d16e8572421130a89c205db737b 100755
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -42,6 +42,7 @@ public:
 	virtual ~LLFloaterConversationPreview(){};
 
 	virtual BOOL postBuild();
+	void SetPages(std::list<LLSD>& messages,const std::string& file_name);
 
 	virtual void draw();
 	virtual void onOpen(const LLSD& key);
@@ -59,6 +60,8 @@ private:
 	std::list<LLSD> mMessages;
 	std::string		mAccountName;
 	std::string		mCompleteName;
+	std::string     mChatHistoryFileName;
+	bool			mChatHistoryLoaded;
 };
 
 #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llfloatergotoline.cpp b/indra/newview/llfloatergotoline.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d66e418926caa5aaaa6db6eedc3ca83d0d0d11f9
--- /dev/null
+++ b/indra/newview/llfloatergotoline.cpp
@@ -0,0 +1,160 @@
+/**
+ * @file llfloatergotoline.h
+ * @author MartinRJ
+ * @brief LLFloaterGotoLine class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llfloatergotoline.h"
+#include "llpreviewscript.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llviewertexteditor.h"
+#include "llviewerwindow.h"
+
+LLFloaterGotoLine* LLFloaterGotoLine::sInstance = NULL;
+
+LLFloaterGotoLine::LLFloaterGotoLine(LLScriptEdCore* editor_core)
+:       LLFloater(LLSD()),
+        mGotoBox(NULL),
+        mEditorCore(editor_core)
+{
+        buildFromFile("floater_goto_line.xml");
+
+        sInstance = this;
+        
+        // find floater in which script panel is embedded
+        LLView* viewp = (LLView*)editor_core;
+        while(viewp)
+        {
+                LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp);
+                if (floaterp)
+                {
+                        floaterp->addDependentFloater(this);
+                        break;
+                }
+                viewp = viewp->getParent();
+        }
+}
+
+BOOL LLFloaterGotoLine::postBuild()
+{
+	mGotoBox = getChild<LLLineEditor>("goto_line");
+	mGotoBox->setCommitCallback(boost::bind(&LLFloaterGotoLine::onGotoBoxCommit, this));
+	mGotoBox->setCommitOnFocusLost(FALSE);
+        getChild<LLLineEditor>("goto_line")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+        childSetAction("goto_btn", onBtnGoto,this);
+        setDefaultBtn("goto_btn");
+
+        return TRUE;
+}
+
+//static 
+void LLFloaterGotoLine::show(LLScriptEdCore* editor_core)
+{
+        if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core)
+        {
+                sInstance->closeFloater();
+                delete sInstance;
+        }
+
+        if (!sInstance)
+        {
+                // sInstance will be assigned in the constructor.
+                new LLFloaterGotoLine(editor_core);
+        }
+
+        sInstance->openFloater();
+}
+
+LLFloaterGotoLine::~LLFloaterGotoLine()
+{
+        sInstance = NULL;
+}
+
+// static 
+void LLFloaterGotoLine::onBtnGoto(void *userdata)
+{
+        LLFloaterGotoLine* self = (LLFloaterGotoLine*)userdata;
+        self->handleBtnGoto();
+}
+
+void LLFloaterGotoLine::handleBtnGoto()
+{
+        S32 row = 0;
+        S32 column = 0;
+        row = getChild<LLUICtrl>("goto_line")->getValue().asInteger();
+        if (row >= 0)
+        {
+                if (mEditorCore && mEditorCore->mEditor)
+                {
+			mEditorCore->mEditor->deselect();
+			mEditorCore->mEditor->setCursor(row, column);
+			mEditorCore->mEditor->setFocus(TRUE);
+                }
+        }
+}
+
+bool LLFloaterGotoLine::hasAccelerators() const
+{
+        if (mEditorCore)
+        {
+                return mEditorCore->hasAccelerators();
+        }
+        return FALSE;
+}
+
+BOOL LLFloaterGotoLine::handleKeyHere(KEY key, MASK mask)
+{
+        if (mEditorCore)
+        {
+                return mEditorCore->handleKeyHere(key, mask);
+        }
+
+        return FALSE;
+}
+
+void LLFloaterGotoLine::onGotoBoxCommit()
+{
+        S32 row = 0;
+        S32 column = 0;
+        row = getChild<LLUICtrl>("goto_line")->getValue().asInteger();
+        if (row >= 0)
+        {
+                if (mEditorCore && mEditorCore->mEditor)
+                {
+			mEditorCore->mEditor->setCursor(row, column);
+
+			S32 rownew = 0;
+			S32 columnnew = 0;
+			mEditorCore->mEditor->getCurrentLineAndColumn( &rownew, &columnnew, FALSE );  // don't include wordwrap
+			if (rownew == row && columnnew == column)
+			{
+			        mEditorCore->mEditor->deselect();
+			        mEditorCore->mEditor->setFocus(TRUE);
+			        sInstance->closeFloater();
+			} //else do nothing (if the cursor-position didn't change)
+                }
+        }
+}
diff --git a/indra/newview/llfloatergotoline.h b/indra/newview/llfloatergotoline.h
new file mode 100644
index 0000000000000000000000000000000000000000..058d6017522a278cda32461413d6d44c547d5017
--- /dev/null
+++ b/indra/newview/llfloatergotoline.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloatergotoline.h
+ * @author MartinRJ
+ * @brief LLFloaterGotoLine class definition
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLFLOATERGOTOLINE_H
+#define LL_LLFLOATERGOTOLINE_H
+
+#include "llfloater.h"
+#include "lllineeditor.h"
+#include "llpreviewscript.h"
+
+class LLScriptEdCore;
+
+class LLFloaterGotoLine : public LLFloater
+{
+public:
+        LLFloaterGotoLine(LLScriptEdCore* editor_core);
+        ~LLFloaterGotoLine();
+
+        /*virtual*/     BOOL    postBuild();
+        static void show(LLScriptEdCore* editor_core);
+
+        static void onBtnGoto(void* userdata);
+        void handleBtnGoto();
+
+        LLScriptEdCore* getEditorCore() { return mEditorCore; }
+        static LLFloaterGotoLine* getInstance() { return sInstance; }
+
+        virtual bool hasAccelerators() const;
+        virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+private:
+
+        LLScriptEdCore* mEditorCore;
+
+        static LLFloaterGotoLine*       sInstance;
+
+protected:
+	LLLineEditor*			mGotoBox;
+        void onGotoBoxCommit();
+};
+
+#endif  // LL_LLFLOATERGOTOLINE_H
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index b40789db9c1b91604f247520aadb622b924e70a5..4591b80ac4610705f6f2b9a57df9db7a4750a564 100755
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -47,6 +47,7 @@
 #include "llfloaterpreference.h"
 #include "llimview.h"
 #include "llnotificationsutil.h"
+#include "lltoolbarview.h"
 #include "lltransientfloatermgr.h"
 #include "llviewercontrol.h"
 #include "llconversationview.h"
@@ -54,6 +55,7 @@
 #include "llworld.h"
 #include "llsdserialize.h"
 #include "llviewerobjectlist.h"
+#include "boost/foreach.hpp"
 
 //
 // LLFloaterIMContainer
@@ -63,7 +65,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL),
 	mConversationsEventStream("ConversationsEvents"),
-	mInitialized(false)
+	mInitialized(false),
+	mIsFirstLaunch(true)
 {
     mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
@@ -113,6 +116,10 @@ void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str
 
 void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
+	if(!isInVisibleChain())
+	{
+		setVisibleAndFrontmost(false);
+	}
 	selectConversationPair(session_id, true);
 	collapseMessagesPane(false);
 }
@@ -204,6 +211,7 @@ BOOL LLFloaterIMContainer::postBuild()
 	// a scroller for folder view
 	LLRect scroller_view_rect = mConversationsListPanel->getRect();
 	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	scroller_view_rect.mBottom += getChild<LLLayoutStack>("conversations_pane_buttons_stack")->getRect().getHeight();
 	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
 	scroller_params.rect(scroller_view_rect);
 
@@ -221,7 +229,8 @@ BOOL LLFloaterIMContainer::postBuild()
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this));
 	mStubCollapseBtn = getChild<LLButton>("stub_collapse_btn");
 	mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this));
-	getChild<LLButton>("speak_btn")->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this));
+    mSpeakBtn = getChild<LLButton>("speak_btn");
+	mSpeakBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this));
 
 	childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
 
@@ -258,7 +267,6 @@ BOOL LLFloaterIMContainer::postBuild()
 void LLFloaterIMContainer::onOpen(const LLSD& key)
 {
 	LLMultiFloater::onOpen(key);
-	openNearbyChat();
 	reSelectConversation();
 	assignResizeLimits();
 }
@@ -593,6 +601,7 @@ void LLFloaterIMContainer::setMinimized(BOOL b)
 	//Switching from minimized to un-minimized
 	if(was_minimized && !b)
 	{
+		gToolBarView->flashCommand(LLCommandId("chat"), false);
 		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
 
 		if(session_floater && !session_floater->isTornOff())
@@ -621,7 +630,6 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
             selectConversationPair(LLUUID(NULL), false, false);
 		}
-		openNearbyChat();
 		flashConversationItemWidget(mSelectedSession,false);
 
 		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
@@ -651,7 +659,11 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
 		if (widget)
 		{
-		    widget->setVisibleIfDetached(visible);
+			LLFloater* session_floater = widget->getSessionFloater();
+			if (session_floater != nearby_chat)
+			{
+				widget->setVisibleIfDetached(visible);
+			}
 		}
 	}
 	
@@ -659,10 +671,37 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 	LLMultiFloater::setVisible(visible);
 }
 
+void LLFloaterIMContainer::getDetachedConversationFloaters(floater_list_t& floaters)
+{
+	typedef conversations_widgets_map::value_type conv_pair;
+	BOOST_FOREACH(conv_pair item, mConversationsWidgets)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(item.second);
+		if (widget)
+		{
+			LLFloater* session_floater = widget->getSessionFloater();
+			if (session_floater && session_floater->isDetachedAndNotMinimized())
+			{
+				floaters.push_back(session_floater);
+			}
+		}
+	}
+}
+
 void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
 {
 	LLMultiFloater::setVisibleAndFrontmost(take_focus, key);
-    selectConversationPair(getSelectedSession(), false, take_focus);
+	// Do not select "Nearby Chat" conversation, since it will bring its window to front
+	// Only select other sessions
+	if (!getSelectedSession().isNull())
+	{
+		selectConversationPair(getSelectedSession(), false, take_focus);
+	}
+	if (mInitialized && mIsFirstLaunch)
+	{
+		collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
+		mIsFirstLaunch = false;
+	}
 }
 
 void LLFloaterIMContainer::updateResizeLimits()
@@ -779,13 +818,6 @@ void LLFloaterIMContainer::reshapeFloaterAndSetResizeLimits(bool collapse, S32 d
 	setCanMinimize(at_least_one_panel_is_expanded);
 
     assignResizeLimits();
-
-    // force set correct size for the title after show/hide minimize button
-	LLRect cur_rect = getRect();
-	LLRect force_rect = cur_rect;
-	force_rect.mRight = cur_rect.mRight + 1;
-    setRect(force_rect);
-    setRect(cur_rect);
 }
 
 void LLFloaterIMContainer::assignResizeLimits()
@@ -793,15 +825,12 @@ void LLFloaterIMContainer::assignResizeLimits()
 	bool is_conv_pane_expanded = !mConversationsPane->isCollapsed();
 	bool is_msg_pane_expanded = !mMessagesPane->isCollapsed();
 
-	// With two panels visible number of borders is three, because the borders
-	// between the panels are merged into one
-    S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);
-    S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH;
-	S32 conv_pane_target_width = is_conv_pane_expanded?
-			(is_msg_pane_expanded?
-					mConversationsPane->getRect().getWidth()
-					: mConversationsPane->getExpandedMinDim())
-			: mConversationsPane->getMinDim();
+    S32 summary_width_of_visible_borders = (is_msg_pane_expanded ? mConversationsStack->getPanelSpacing() : 0) + 1;
+
+	S32 conv_pane_target_width = is_conv_pane_expanded
+		? ( is_msg_pane_expanded?mConversationsPane->getRect().getWidth():mConversationsPane->getExpandedMinDim() )
+		: mConversationsPane->getMinDim();
+
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
 	S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders;
 
@@ -961,11 +990,11 @@ void LLFloaterIMContainer::setSortOrder(const LLConversationSort& order)
 			conversation_floater->setSortOrder(order);
 		}
 	}
-	
+
 	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
 }
 
-void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids, bool participant_uuids/* = true*/)
 {
     const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
 
@@ -978,7 +1007,7 @@ void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
         conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
       
 		//When a one-on-one conversation exists, retrieve the participant id from the conversation floater
-		if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+		if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1 && participant_uuids)
 		{
 			LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversationItem->getUUID());
 			LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID();
@@ -1133,6 +1162,11 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
         {
             LLFloater::onClickClose(conversationFloater);
         }
+        else if("close_selected_conversations" == command)
+        {
+        	getSelectedUUIDs(selectedIDS,false);
+        	closeSelectedConversations(selectedIDS);
+        }
         else if("open_voice_conversation" == command)
         {
             gIMMgr->startCall(conversationItem->getUUID());
@@ -1143,7 +1177,7 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
         }
         else if("chat_history" == command)
         {
-			if (selectedIDS.size() > 0)
+        	if (selectedIDS.size() > 0)
 			{
 				LLAvatarActions::viewChatHistory(selectedIDS.front());
 			}
@@ -1156,6 +1190,17 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
         	}
         }
     }
+    //if there is no LLFloaterIMSession* instance for selected conversation it might be Nearby chat
+    else
+    {
+    	if(conversationItem->getType() == LLConversationItem::CONV_SESSION_NEARBY)
+    	{
+    		if("chat_history" == command)
+    	    {
+    	      	LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
+    	    }
+    	}
+    }
 }
 
 void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
@@ -1185,7 +1230,7 @@ void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata)
 
     if (action == "group_profile")
     {
-        LLGroupActions::show(mSelectedSession);
+    	LLGroupActions::show(mSelectedSession);
     }
     else if (action == "activate_group")
     {
@@ -1211,7 +1256,19 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	//Enable Chat history item for ad-hoc and group conversations
 	if ("can_chat_history" == item && uuids.size() > 0)
 	{
-		return LLLogChat::isTranscriptExist(uuids.front());
+		//Disable menu item if selected participant is user agent
+		if(uuids.front() != gAgentID)
+		{
+			if (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_NEARBY)
+			{
+				return LLLogChat::isNearbyTranscriptExist();
+			}
+			else
+			{
+				bool is_group = (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP);
+				return LLLogChat::isTranscriptExist(uuids.front(),is_group);
+			}
+		}
 	}
 
 	// If nothing is selected(and selected item is not group chat), everything needs to be disabled
@@ -1886,13 +1943,6 @@ void LLFloaterIMContainer::openNearbyChat()
 	}
 }
 
-void LLFloaterIMContainer::onNearbyChatClosed()
-{
-	// If nearby chat is the only remaining conversation and it is closed, close whole conversation floater as well
-	if (mConversationsItems.size() == 1)
-		closeFloater();
-}
-
 void LLFloaterIMContainer::reSelectConversation()
 {
 	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
@@ -1904,7 +1954,6 @@ void LLFloaterIMContainer::reSelectConversation()
 
 void LLFloaterIMContainer::updateSpeakBtnState()
 {
-	LLButton* mSpeakBtn = getChild<LLButton>("speak_btn");
 	mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState());
 	mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak"));
 }
@@ -1925,6 +1974,17 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id,
 	}
 }
 
+void LLFloaterIMContainer::highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted)
+{
+	//Finds the conversation line item to highlight using the session_id
+	LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
+
+	if (widget)
+	{
+		widget->setHighlightState(is_highlighted);
+	}
+}
+
 bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget)
 {
 	llassert(conversation_item_widget != NULL);
@@ -1940,23 +2000,28 @@ bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conve
 
 BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask )
 {
+	BOOL handled = FALSE;
+
 	if(mask == MASK_ALT)
 	{
 		if (KEY_RETURN == key )
 		{
 			expandConversation();
+			handled = TRUE;
 		}
 
 		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
 		{
 			selectNextorPreviousConversation(true);
+			handled = TRUE;
 		}
 		if ((KEY_UP == key) || (KEY_LEFT == key))
 		{
 			selectNextorPreviousConversation(false);
+			handled = TRUE;
 		}
 	}
-	return TRUE;
+	return handled;
 }
 
 bool LLFloaterIMContainer::selectAdjacentConversation(bool focus_selected)
@@ -2013,7 +2078,22 @@ void LLFloaterIMContainer::expandConversation()
 	}
 }
 
-void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
+// By default, if torn off session is currently frontmost, LLFloater::isFrontmost() will return FALSE, which can lead to some bugs
+// So LLFloater::isFrontmost() is overriden here to check both selected session and the IM floater itself
+// Exclude "Nearby Chat" session from the check, as "Nearby Chat" window and "Conversations" floater can be brought
+// to front independently
+/*virtual*/
+BOOL LLFloaterIMContainer::isFrontmost()
+{
+	LLFloaterIMSessionTab* selected_session = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	return (selected_session && selected_session->isFrontmost() && (selected_session != nearby_chat))
+		|| LLFloater::isFrontmost();
+}
+
+// For conversations, closeFloater() (linked to Ctrl-W) does not actually close the floater but the active conversation.
+// This is intentional so it doesn't confuse the user. onClickCloseBtn() closes the whole floater.
+void LLFloaterIMContainer::onClickCloseBtn()
 {
 	// Always unminimize before trying to close.
 	// Most of the time the user will never see this state.
@@ -2022,7 +2102,80 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
 		LLMultiFloater::setMinimized(FALSE);
 	}
 
-	LLFloater::closeFloater(app_quitting);
+	LLFloater::closeFloater();
+}
+
+void LLFloaterIMContainer::closeHostedFloater()
+{
+	onClickCloseBtn();
+}
+
+void LLFloaterIMContainer::closeAllConversations()
+{
+	LLDynamicArray<LLUUID> ids;
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		LLUUID session_id = it_session->first;
+		if (session_id != LLUUID())
+		{
+			ids.push_back(session_id);
+		}
+	}
+
+	for (LLDynamicArray<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); 	++it)
+	{
+		LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it);
+		LLFloater::onClickClose(conversationFloater);
+	}
+}
+
+void LLFloaterIMContainer::closeSelectedConversations(const uuid_vec_t& ids)
+{
+	for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		//We don't need to close Nearby chat, so skip it
+		if (*it != LLUUID())
+		{
+			LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it);
+			if(conversationFloater)
+			{
+				LLFloater::onClickClose(conversationFloater);
+			}
+		}
+	}
+}
+void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
+{
+	if(app_quitting)
+	{
+		closeAllConversations();
+		onClickCloseBtn();
+	}
+	else
+	{
+		// Check for currently active session
+		LLUUID session_id = getSelectedSession();
+		// If current session is Nearby Chat or there is only one session remaining, close the floater
+		if (mConversationsItems.size() == 1 || session_id == LLUUID() || app_quitting)
+		{
+			onClickCloseBtn();
+		}
+		else
+		{
+			// Otherwise, close current conversation
+			LLFloaterIMSessionTab* active_conversation = LLFloaterIMSessionTab::getConversation(session_id);
+			if (active_conversation)
+			{
+				active_conversation->closeFloater();
+			}
+		}
+	}
+}
+
+void LLFloaterIMContainer::handleReshape(const LLRect& rect, bool by_user)
+{
+	LLMultiFloater::handleReshape(rect, by_user);
+	storeRectControl();
 }
 
 // EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index e39d20ec35880415da2e381efc7fb9a071f452d2..36da457cacfb5f34ee4f549eb652ef81ff575a9a 100755
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -63,6 +63,8 @@ public:
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
 	/*virtual*/ void updateResizeLimits();
+	/*virtual*/ void handleReshape(const LLRect& rect, bool by_user);
+
 	void onCloseFloater(LLUUID& id);
 
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
@@ -105,8 +107,6 @@ public:
 	LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); }
 	LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); }
 
-	void onNearbyChatClosed();
-
 	// Handling of lists of participants is public so to be common with llfloatersessiontab
 	// *TODO : Find a better place for this.
     bool checkContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
@@ -116,6 +116,10 @@ public:
 	void assignResizeLimits();
 	virtual BOOL handleKeyHere(KEY key, MASK mask );
 	/*virtual*/ void closeFloater(bool app_quitting = false);
+    void closeAllConversations();
+    void closeSelectedConversations(const uuid_vec_t& ids);
+	/*virtual*/ BOOL isFrontmost();
+
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
@@ -130,6 +134,8 @@ private:
 	void onStubCollapseButtonClicked();
 	void processParticipantsStyleUpdate();
 	void onSpeakButtonClicked();
+	/*virtual*/ void onClickCloseBtn();
+	/*virtual*/ void closeHostedFloater();
 
 	void collapseConversationsPane(bool collapse, bool save_is_allowed=true);
 
@@ -144,7 +150,7 @@ private:
 	void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
 	void setSortOrder(const LLConversationSort& order);
 
-    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids, bool participant_uuids = true);
     const LLConversationItem * getCurSelectedViewModelItem();
     void getParticipantUUIDs(uuid_vec_t& selected_uuids);
     void doToSelected(const LLSD& userdata);
@@ -169,6 +175,7 @@ private:
 
 	LLButton* mExpandCollapseBtn;
 	LLButton* mStubCollapseBtn;
+    LLButton* mSpeakBtn;
 	LLPanel* mStubPanel;
 	LLTextBox* mStubTextBox;
 	LLLayoutPanel* mMessagesPane;
@@ -176,6 +183,7 @@ private:
 	LLLayoutStack* mConversationsStack;
 	
 	bool mInitialized;
+	bool mIsFirstLaunch;
 
 	LLUUID mSelectedSession;
 	std::string mGeneralTitle;
@@ -190,9 +198,12 @@ public:
 	void updateSpeakBtnState();
 	static bool isConversationLoggingAllowed();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
+	void highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted);
 	bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget);
 	boost::signals2::connection mMicroChangedSignal;
 	S32 getConversationListItemSize() { return mConversationsWidgets.size(); }
+	typedef std::list<LLFloater*> floater_list_t;
+	void getDetachedConversationFloaters(floater_list_t& floaters);
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 56b0c15cb9e8ec03157270f9ef3e45ec0d04b085..3d77ea4f0bb3ab7fc1861214f39b125173e0ae68 100755
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -125,7 +125,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 	setTitle(LLTrans::getString("NearbyChatTitle"));
 
 	// obsolete, but may be needed for backward compatibility?
-	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
+	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", LLControlVariable::PERSIST_NONDFT);
 
 	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
 	{
@@ -138,19 +138,28 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 // virtual
 void LLFloaterIMNearbyChat::closeHostedFloater()
 {
-	// Should check how many conversations are ongoing. Close all if 1 only (the Nearby Chat), select next one otherwise
+	// If detached from conversations window close anyway
+	if (!getHost())
+	{
+		setVisible(FALSE);
+	}
+
+	// Should check how many conversations are ongoing. Select next to "Nearby Chat" in case there are some other besides.
+	// Close conversations window in case "Nearby Chat" is attached and the only conversation
 	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
 	if (floater_container->getConversationListItemSize() == 1)
 	{
-		floater_container->closeFloater();
+		if (getHost())
+		{
+			floater_container->closeFloater();
+		}
 	}
 	else
 	{
 		if (!getHost())
 		{
-			setVisible(FALSE);
+			floater_container->selectNextConversationByID(LLUUID());
 		}
-		floater_container->selectNextConversationByID(LLUUID());
 	}
 }
 
@@ -262,7 +271,7 @@ void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD&
 {
 	LLFloaterIMSessionTab::setVisibleAndFrontmost(take_focus, key);
 
-	if(!isTornOff() && matchesKey(key))
+	if(matchesKey(key))
 	{
 		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, take_focus);
 	}
@@ -296,7 +305,6 @@ void LLFloaterIMNearbyChat::onClose(bool app_quitting)
 {
 	// Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater
 	LLFloaterIMSessionTab::restoreFloater();
-	onClickCloseBtn();
 }
 
 // virtual
@@ -306,13 +314,7 @@ void LLFloaterIMNearbyChat::onClickCloseBtn()
 	{
 		return;
 	}
-	LLFloaterIMSessionTab::onTearOffClicked();
-	
-	LLFloaterIMContainer *im_box = LLFloaterIMContainer::findInstance();
-	if (im_box)
-	{
-		im_box->onNearbyChatClosed();
-	}
+	closeHostedFloater();
 }
 
 void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
@@ -350,11 +352,17 @@ bool LLFloaterIMNearbyChat::isChatVisible() const
 void LLFloaterIMNearbyChat::showHistory()
 {
 	openFloater();
+	LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));
+
 	if(!isMessagePaneExpanded())
 	{
 		restoreFloater();
 		setFocus(true);
 	}
+	else
+	{
+		LLFloaterIMContainer::getInstance()->setFocus(TRUE);
+	}
 	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
 }
 
@@ -568,7 +576,10 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type )
 			if (0 == channel)
 			{
 				// discard returned "found" boolean
-				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
+				if(!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text))
+				{
+					utf8_revised_text = utf8text;
+				}
 			}
 			else
 			{
@@ -582,7 +593,7 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type )
 			if (!utf8_revised_text.empty())
 			{
 				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
+				sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim"));
 			}
 		}
 
@@ -636,10 +647,7 @@ void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLS
 
 void LLFloaterIMNearbyChat::onChatBoxCommit()
 {
-	if (mInputEditor->getText().length() > 0)
-	{
-		sendChat(CHAT_TYPE_NORMAL);
-	}
+	sendChat(CHAT_TYPE_NORMAL);
 
 	gAgent.stopTyping();
 }
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 9ce5e128977e0b889acc0b40cd24a90d97c4bdae..cc00b6fd10d88f61e1cc9b3ed0eec40c5e44d367 100755
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -606,6 +606,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 
 		//Don't show nearby toast, if conversation is visible and selected
 		if ((nearby_chat->hasFocus()) ||
+			(LLFloater::isVisible(nearby_chat) && nearby_chat->isTornOff() && !nearby_chat->isMinimized()) ||
 		    ((im_box->getSelectedSession().isNull() &&
 				((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost())
 						|| (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))))
diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp
index 14a22bcd84cb2f0f7b0936796ef10037272dba98..5a5f6c72c8ce29beeed6db1e3fb1dbd75e7b215c 100755
--- a/indra/newview/llfloaterimnearbychatlistener.cpp
+++ b/indra/newview/llfloaterimnearbychatlistener.cpp
@@ -33,7 +33,7 @@
 
 #include "llagent.h"
 #include "llchat.h"
-
+#include "llviewercontrol.h"
 
 
 LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar)
@@ -95,6 +95,6 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const
 	}
 
 	// Send it as if it was typed in
-	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0));
+	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim"));
 }
 
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 8ec85e11602709d7791b9d95c9d08251b8152960..5cb9df5625895f96c22dcfb1c9e58aa1195af85c 100755
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -109,18 +109,6 @@ void LLFloaterIMSession::refresh()
 void LLFloaterIMSession::onTearOffClicked()
 {
     LLFloaterIMSessionTab::onTearOffClicked();
-
-    if(mIsP2PChat)
-    {
-        if(isTornOff())
-        {
-            mSpeakingIndicator->setSpeakerId(mOtherParticipantUUID, mSessionID);
-        }
-        else
-        {
-            mSpeakingIndicator->setSpeakerId(LLUUID::null);
-        }
-    }
 }
 
 // virtual
@@ -442,8 +430,11 @@ void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids)
 	}
 	else
 	{
-		// remember whom we have invited, to notify others later, when the invited ones actually join
-		mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+		if(findInstance(mSessionID))
+		{
+			// remember whom we have invited, to notify others later, when the invited ones actually join
+			mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+		}
 		
 		inviteToSession(uuids);
 	}
@@ -469,13 +460,18 @@ void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, con
 	temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
 
 	// then we can close the current session
-	onClose(false);
+	if(findInstance(mSessionID))
+	{
+		onClose(false);
+
+		// remember whom we have invited, to notify others later, when the invited ones actually join
+		mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+	}
 
 	// we start a new session so reset the initialization flag
 	mSessionInitialized = false;
 
-	// remember whom we have invited, to notify others later, when the invited ones actually join
-	mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+
 
 	// Start a new ad hoc voice call if we invite new participants to a P2P call,
 	// or start a text chat otherwise.
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index ce6e639305b345a16fbc8e3738397144167d8957..0ccfdb9a7be79718c1c8f1a55f29c61fd2b2e06e 100755
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -55,7 +55,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   ,  mSessionID(session_id.asUUID())
   , mConversationsRoot(NULL)
   , mScroller(NULL)
-  , mSpeakingIndicator(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
   , mInputEditorPad(0)
@@ -212,7 +211,7 @@ void LLFloaterIMSessionTab::assignResizeLimits()
 	mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed);
 
     S32 participants_pane_target_width = is_participants_pane_collapsed?
-    		0 : (mParticipantListPanel->getRect().getWidth() + LLPANEL_BORDER_WIDTH);
+    		0 : (mParticipantListPanel->getRect().getWidth() + mParticipantListAndHistoryStack->getPanelSpacing());
 
     S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
 
@@ -241,7 +240,10 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
 
 	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");
 
@@ -256,8 +258,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	scroller_params.rect(scroller_view_rect);
 	mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
 	mScroller->setFollowsAll();
-	
-    mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 
 	// Insert that scroller into the panel widgets hierarchy
 	mParticipantListPanel->addChild(mScroller);	
@@ -270,6 +270,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mInputPanels = getChild<LLLayoutStack>("input_panels");
 	
 	mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this));
+	mInputEditor->setMouseUpCallback(boost::bind(&LLFloaterIMSessionTab::onInputEditorClicked, this));
 	mInputEditor->setCommitOnFocusLost( FALSE );
 	mInputEditor->setPassDelete(TRUE);
 	mInputEditor->setFont(LLViewerChat::getChatFont());
@@ -372,7 +373,7 @@ void LLFloaterIMSessionTab::draw()
 
 void LLFloaterIMSessionTab::enableDisableCallBtn()
 {
-    getChildView("voice_call_btn")->setEnabled(
+    mVoiceButton->setEnabled(
     		mSessionID.notNull()
     		&& mSession
     		&& mSession->mSessionInitialized
@@ -399,6 +400,16 @@ void LLFloaterIMSessionTab::onFocusLost()
 	LLTransientDockableFloater::onFocusLost();
 }
 
+void LLFloaterIMSessionTab::onInputEditorClicked()
+{
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->flashConversationItemWidget(mSessionID,false);
+	}
+	gToolBarView->flashCommand(LLCommandId("chat"), false);
+}
+
 std::string LLFloaterIMSessionTab::appendTime()
 {
 	time_t utc_time;
@@ -758,7 +769,7 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
 
 void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
 {
-	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
+	mTranslationCheckBox->setVisible(mIsNearbyChat && show);
 }
 
 // static
@@ -805,15 +816,10 @@ void LLFloaterIMSessionTab::reloadEmptyFloaters()
 
 void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
 {
-	LLButton* voiceButton = getChild<LLButton>("voice_call_btn");
-	voiceButton->setImageOverlay(
-			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
-
-	voiceButton->setToolTip(
-			callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip"));
+	mVoiceButton->setImageOverlay(callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
+	mVoiceButton->setToolTip(callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip"));
 
 	enableDisableCallBtn();
-
 }
 
 void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
@@ -898,6 +904,7 @@ void LLFloaterIMSessionTab::restoreFloater()
 		mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
 		setMessagePaneExpanded(true);
 		saveCollapsedState();
+		mInputEditor->enableSingleLineMode(false);
 		enableResizeCtrls(true, true, true);
 	}
 }
@@ -953,8 +960,8 @@ void LLFloaterIMSessionTab::updateGearBtn()
 	if(prevVisibility != mGearBtn->getVisible())
 	{
 		LLRect gear_btn_rect =  mGearBtn->getRect();
-		LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
-		LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+		LLRect add_btn_rect = mAddBtn->getRect();
+		LLRect call_btn_rect = mVoiceButton->getRect();
 		S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
 		S32 right_shift = gear_btn_rect.getWidth() + gap_width;
 		if(mGearBtn->getVisible())
@@ -968,24 +975,24 @@ void LLFloaterIMSessionTab::updateGearBtn()
 			add_btn_rect.translate(-right_shift,0);
 			call_btn_rect.translate(-right_shift,0);
 		}
-		getChild<LLButton>("add_btn")->setRect(add_btn_rect);
-		getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
+		mAddBtn->setRect(add_btn_rect);
+		mVoiceButton->setRect(call_btn_rect);
 	}
 }
 
 void LLFloaterIMSessionTab::initBtns()
 {
 	LLRect gear_btn_rect =  mGearBtn->getRect();
-	LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
-	LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+	LLRect add_btn_rect = mAddBtn->getRect();
+	LLRect call_btn_rect = mVoiceButton->getRect();
 	S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
 	S32 right_shift = gear_btn_rect.getWidth() + gap_width;
 
 	add_btn_rect.translate(-right_shift,0);
 	call_btn_rect.translate(-right_shift,0);
 
-	getChild<LLButton>("add_btn")->setRect(add_btn_rect);
-	getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
+	mAddBtn->setRect(add_btn_rect);
+	mVoiceButton->setRect(call_btn_rect);
 }
 
 // static
@@ -1083,21 +1090,26 @@ void LLFloaterIMSessionTab::saveCollapsedState()
 }
 BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
 {
+	BOOL handled = FALSE;
+
 	if(mask == MASK_ALT)
 	{
 		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
 		if (KEY_RETURN == key && !isTornOff())
 		{
 			floater_container->expandConversation();
+			handled = TRUE;
 		}
 		if ((KEY_UP == key) || (KEY_LEFT == key))
 		{
 			floater_container->selectNextorPreviousConversation(false);
+			handled = TRUE;
 		}
 		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
 		{
 			floater_container->selectNextorPreviousConversation(true);
+			handled = TRUE;
 		}
 	}
-	return TRUE;
+	return handled;
 }
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 302d5a8066f5efed30be8a303a343bdffccd47be..e7b05a584bd998ab11f2911a943643d806d62450 100755
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -171,8 +171,7 @@ protected:
 	LLFolderView* mConversationsRoot;
 	LLScrollContainer* mScroller;
 
-    LLOutputMonitorCtrl* mSpeakingIndicator;
-	LLChatHistory* mChatHistory;
+    LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
 	LLLayoutPanel * mChatLayoutPanel;
 	LLLayoutStack * mInputPanels;
@@ -182,6 +181,9 @@ protected:
 	LLButton* mTearOffBtn;
 	LLButton* mCloseBtn;
 	LLButton* mGearBtn;
+	LLButton* mAddBtn;
+    LLButton* mVoiceButton;
+    LLUICtrl* mTranslationCheckBox;
 
 private:
 	// Handling selection and contextual menu
@@ -201,6 +203,8 @@ private:
 	 */
 	void reshapeChatLayoutPanel();
 
+	void onInputEditorClicked();
+
 	bool checkIfTornOff();
     bool mIsHostAttached;
     bool mHasVisibleBeenInitialized;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 55b03986d01098f3975c6121afbccb0b70727fb6..4ebe813be63d510ef9d2044b51ae5ad6be10529b 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -452,6 +452,7 @@ BOOL LLFloaterPreference::postBuild()
 	getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions"));
 	getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions"));
 	getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions"));
+	getChild<LLComboBox>("ObjectIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ObjectIMOptions"));
 
 	// if floater is opened before login set default localized do not disturb message
 	if (LLStartUp::getStartupState() < STATE_STARTED)
@@ -721,6 +722,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	onNotificationsChange("ConferenceIMOptions");
 	onNotificationsChange("GroupChatOptions");
 	onNotificationsChange("NearbyChatOptions");
+	onNotificationsChange("ObjectIMOptions");
 
 	LLPanelLogin::setAlwaysRefresh(true);
 	refresh();
@@ -928,7 +930,7 @@ void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
 	bool show_notifications_alert = true;
 	for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++)
 	{
-		if(it_notification->second != "None")
+		if(it_notification->second != "No action")
 		{
 			show_notifications_alert = false;
 			break;
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 586965e5a007b094dcc22e4e808f79190589f3c2..c28657dbcd3df4f290cb18f82f1e163461604205 100755
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -74,6 +74,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 		it != end_it;
 		++it)
 	{
+        // Recursive call to sort() on child (CHUI-849)
 		LLFolderViewFolder* child_folderp = *it;
 		sort(child_folderp);
 
@@ -129,12 +130,12 @@ void LLFolderViewModelItemInventory::requestSort()
 void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
 {
 	LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size);
-
-	bool passed_filter_before = mPrevPassedAllFilters;
+	bool before = mPrevPassedAllFilters;
 	mPrevPassedAllFilters = passedFilter(filter_generation);
 
-	if (passed_filter_before != mPrevPassedAllFilters)
+    if (before != mPrevPassedAllFilters)
 	{
+        // Need to rearrange the folder if the filtered state of the item changed
 		LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
 		if (parent_folder)
 		{
@@ -150,11 +151,11 @@ bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 	bool continue_filtering = true;
 	if (item->getLastFilterGeneration() < filter_generation)
 	{
-		// recursive application of the filter for child items
+		// Recursive application of the filter for child items (CHUI-849)
 		continue_filtering = item->filter( filter );
 	}
 
-	// track latest generation to pass any child items, for each folder up to root
+	// Update latest generation to pass filter in parent and propagate up to root
 	if (item->passedFilter())
 	{
 		LLFolderViewModelItemInventory* view_model = this;
@@ -174,53 +175,61 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 	const S32 filter_generation = filter.getCurrentGeneration();
 	const S32 must_pass_generation = filter.getFirstRequiredGeneration();
 
-	if (getLastFilterGeneration() >= must_pass_generation 
+    if (getLastFilterGeneration() >= must_pass_generation
 		&& getLastFolderFilterGeneration() >= must_pass_generation
 		&& !passedFilter(must_pass_generation))
 	{
 		// failed to pass an earlier filter that was a subset of the current one
-		// go ahead and flag this item as done
+		// go ahead and flag this item as not pass
 		setPassedFilter(false, filter_generation);
 		setPassedFolderFilter(false, filter_generation);
 		return true;
 	}
 
-	const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) 
-		? filter.checkFolder(this)
-		: true;
+    // *TODO : Revise the logic for fast pass on less restrictive filter case
+    /*
+     const S32 sufficient_pass_generation = filter.getFirstSuccessGeneration();
+    if (getLastFilterGeneration() >= sufficient_pass_generation
+		&& getLastFolderFilterGeneration() >= sufficient_pass_generation
+		&& passedFilter(sufficient_pass_generation))
+	{
+		// passed an earlier filter that was a superset of the current one
+		// go ahead and flag this item as pass
+		setPassedFilter(true, filter_generation);
+		setPassedFolderFilter(true, filter_generation);
+		return true;
+	}
+     */
+    
+	const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) ? filter.checkFolder(this) : true;
 	setPassedFolderFilter(passed_filter_folder, filter_generation);
 
-	if(!mChildren.empty()
+	bool continue_filtering = true;
+
+	if (!mChildren.empty()
 		&& (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass
-			|| descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement
+            || descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement
 	{
 		// now query children
-		for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end();
-			iter != end_iter && filter.getFilterCount() > 0;
-			++iter)
+		for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end(); iter != end_iter; ++iter)
 		{
-			if (!filterChildItem((*iter), filter))
+			continue_filtering = filterChildItem((*iter), filter);
+            if (!continue_filtering)
 			{
 				break;
 			}
 		}
 	}
 
-	// if we didn't use all filter iterations
-	// that means we filtered all of our descendants
-	// so filter ourselves now
-	if (filter.getFilterCount() > 0)
+	// If we didn't use all the filter time that means we filtered all of our descendants so we can filter ourselves now
+    if (continue_filtering)
 	{
-		filter.decrementFilterCount();
-
+        // This is where filter check on the item done (CHUI-849)
 		const bool passed_filter = filter.check(this);
 		setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
-		return true;
-	}
-	else
-	{
-		return false;
+        continue_filtering = !filter.isTimedOut();
 	}
+    return continue_filtering;
 }
 
 LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
@@ -307,8 +316,8 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
 	}
 }
 
-LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) 
-	:	LLFolderViewModelItemCommon(root_view_model),
-	mPrevPassedAllFilters(false)
+LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) :
+    LLFolderViewModelItemCommon(root_view_model),
+    mPrevPassedAllFilters(false)
 {
 }
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index 890d03d1c9cf29e48c4a20fe2a4260f5545f1857..9dcfdfa185f83f12c548ffaee3c2d7adcecdb2ce 100755
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -59,9 +59,8 @@ public:
 
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
 	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
-
 protected:
-	bool								mPrevPassedAllFilters;
+    bool mPrevPassedAllFilters;
 };
 
 class LLInventorySort
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index a0f2918bd786338340f7b9fa606c2021ef2323b2..302d21c2e42b16f24ca1b1ed628c412026b87280 100755
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -116,6 +116,80 @@ public:
 };
 LLGroupHandler gGroupHandler;
 
+// This object represents a pending request for specified group member information
+// which is needed to check whether avatar can leave group
+class LLFetchGroupMemberData : public LLGroupMgrObserver
+{
+public:
+	LLFetchGroupMemberData(const LLUUID& group_id) : 
+		mGroupId(group_id),
+		mRequestProcessed(false),
+		LLGroupMgrObserver(group_id) 
+	{
+		llinfos << "Sending new group member request for group_id: "<< group_id << llendl;
+		LLGroupMgr* mgr = LLGroupMgr::getInstance();
+		// register ourselves as an observer
+		mgr->addObserver(this);
+		// send a request
+		mgr->sendGroupPropertiesRequest(group_id);
+		mgr->sendCapGroupMembersRequest(group_id);
+	}
+
+	~LLFetchGroupMemberData()
+	{
+		if (!mRequestProcessed)
+		{
+			// Request is pending
+			llwarns << "Destroying pending group member request for group_id: "
+				<< mGroupId << llendl;
+		}
+		// Remove ourselves as an observer
+		LLGroupMgr::getInstance()->removeObserver(this);
+	}
+
+	void changed(LLGroupChange gc)
+	{
+		if (gc == GC_MEMBER_DATA && !mRequestProcessed)
+		{
+			LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId);
+			if (!gdatap)
+			{
+				llwarns << "LLGroupMgr::getInstance()->getGroupData() was NULL" << llendl;
+			} 
+			else if (!gdatap->isMemberDataComplete())
+			{
+				llwarns << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << llendl;
+			}
+			else
+			{
+				processGroupData();
+				mRequestProcessed = true;
+			}
+		}
+	}
+
+	LLUUID getGroupId() { return mGroupId; }
+	virtual void processGroupData() = 0;
+protected:
+	LLUUID mGroupId;
+private:
+	bool mRequestProcessed;
+};
+
+class LLFetchLeaveGroupData: public LLFetchGroupMemberData
+{
+public:
+	 LLFetchLeaveGroupData(const LLUUID& group_id)
+		 : LLFetchGroupMemberData(group_id)
+	 {}
+	 void processGroupData()
+	 {
+		 LLGroupActions::processLeaveGroupDataResponse(mGroupId);
+	 }
+};
+
+LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
+
 // static
 void LLGroupActions::search()
 {
@@ -208,23 +282,52 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response)
 void LLGroupActions::leave(const LLUUID& group_id)
 {
 	if (group_id.isNull())
+	{
 		return;
+	}
 
-	S32 count = gAgent.mGroups.count();
-	S32 i;
-	for (i = 0; i < count; ++i)
+	LLGroupData group_data;
+	if (gAgent.getGroupData(group_id, group_data))
 	{
-		if(gAgent.mGroups.get(i).mID == group_id)
-			break;
+		LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);
+		if (!gdatap || !gdatap->isMemberDataComplete())
+		{
+			if (gFetchLeaveGroupData != NULL)
+			{
+				delete gFetchLeaveGroupData;
+				gFetchLeaveGroupData = NULL;
+			}
+			gFetchLeaveGroupData = new LLFetchLeaveGroupData(group_id);
+		}
+		else
+		{
+			processLeaveGroupDataResponse(group_id);
+		}
 	}
-	if (i < count)
+}
+
+//static
+void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id)
+{
+	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);
+	LLUUID agent_id = gAgent.getID();
+	LLGroupMgrGroupData::member_list_t::iterator mit = gdatap->mMembers.find(agent_id);
+	//get the member data for the group
+	if ( mit != gdatap->mMembers.end() )
 	{
-		LLSD args;
-		args["GROUP"] = gAgent.mGroups.get(i).mName;
-		LLSD payload;
-		payload["group_id"] = group_id;
-		LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
+		LLGroupMemberData* member_data = (*mit).second;
+
+		if ( member_data && member_data->isOwner() && gdatap->mMemberCount == 1)
+		{
+			LLNotificationsUtil::add("OwnerCannotLeaveGroup");
+			return;
+		}
 	}
+	LLSD args;
+	args["GROUP"] = gdatap->mName;
+	LLSD payload;
+	payload["group_id"] = group_id;
+	LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
 }
 
 // static
diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h
index 3f9852f194550d302aa2db12c2002c431c50412f..afc4686dd77c00fcda9d9ecd8b759b07b0cc52fd 100755
--- a/indra/newview/llgroupactions.h
+++ b/indra/newview/llgroupactions.h
@@ -114,6 +114,14 @@ public:
 private:
 	static bool onJoinGroup(const LLSD& notification, const LLSD& response);
 	static bool onLeaveGroup(const LLSD& notification, const LLSD& response);
+	
+	/**
+	 * This function is called by LLFetchLeaveGroupData upon receiving a response to a group 
+	 * members data request.
+	 */
+	static void processLeaveGroupDataResponse(const LLUUID group_id);
+
+	friend class LLFetchLeaveGroupData;
 };
 
 #endif // LL_LLGROUPACTIONS_H
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3b72ad3cd9f068084998185dc1cdcb5cfcd558cc..9e23755d731a00ff38b6e0640cb90a2f5f9883eb 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -103,6 +103,7 @@ BOOL LLSessionTimeoutTimer::tick()
 }
 
 
+void notify_of_message(const LLSD& msg, bool is_dnd_msg);
 
 void process_dnd_im(const LLSD& notification)
 {
@@ -129,15 +130,9 @@ void process_dnd_im(const LLSD& notification)
             fromID, 
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
+	}
 
-		LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-		
-		if (im_box)
-		{
-			im_box->flashConversationItemWidget(sessionID, true);
-		}
-
-    }
+	notify_of_message(data, true);
 }
 
 
@@ -158,75 +153,106 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
-void on_new_message(const LLSD& msg)
+void notify_of_message(const LLSD& msg, bool is_dnd_msg)
 {
-    std::string user_preferences;
-    LLUUID participant_id = msg["from_id"].asUUID();
-    LLUUID session_id = msg["session_id"].asUUID();
-    LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
-
-    // do not show notification which goes from agent
-    if (gAgent.getID() == participant_id)
-    {
-        return;
-    }
+	std::string user_preferences;
+	LLUUID participant_id = msg[is_dnd_msg ? "FROM_ID" : "from_id"].asUUID();
+	LLUUID session_id = msg[is_dnd_msg ? "SESSION_ID" : "session_id"].asUUID();
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 
-    // determine state of conversations floater
-    enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status;
+	// do not show notification which goes from agent
+	if (gAgent.getID() == participant_id)
+	{
+		return;
+	}
 
+	// determine state of conversations floater
+	enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status;
 
 
-    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
-
+	bool store_dnd_message = false; // flag storage of a dnd message
+	bool is_session_focused = session_floater->isTornOff() && session_floater->hasFocus();
 	if (!LLFloater::isVisible(im_box) || im_box->isMinimized())
 	{
 		conversations_floater_status = CLOSED;
 	}
 	else if (!im_box->hasFocus() &&
-			    !(session_floater && LLFloater::isVisible(session_floater)
-	            && !session_floater->isMinimized() && session_floater->hasFocus()))
+		!(session_floater && LLFloater::isVisible(session_floater)
+		&& !session_floater->isMinimized() && session_floater->hasFocus()))
 	{
 		conversations_floater_status = NOT_ON_TOP;
 	}
 	else if (im_box->getSelectedSession() != session_id)
 	{
 		conversations_floater_status = ON_TOP;
-    }
+	}
 	else
 	{
 		conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED;
 	}
 
-    //  determine user prefs for this session
-    if (session_id.isNull())
-    {
-    	user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions");
-    }
-    else if(session->isP2PSessionType())
-    {
-        if (LLAvatarTracker::instance().isBuddy(participant_id))
-        {
-        	user_preferences = gSavedSettings.getString("NotificationFriendIMOptions");
-        }
-        else
-        {
-        	user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions");
-        }
-    }
-    else if(session->isAdHocSessionType())
-    {
-    	user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions");
-    }
-    else if(session->isGroupSessionType())
-    {
-    	user_preferences = gSavedSettings.getString("NotificationGroupChatOptions");
-    }
+	//  determine user prefs for this session
+	if (session_id.isNull())
+	{
+		if (msg["source_type"].asInteger() == CHAT_SOURCE_OBJECT)
+		{
+			user_preferences = gSavedSettings.getString("NotificationObjectIMOptions");
+			if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundObjectIM") == TRUE))
+			{
+				make_ui_sound("UISndNewIncomingIMSession");
+			}
+		}
+		else
+		{
+			user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions");
+			if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNearbyChatIM") == TRUE))
+			{
+				make_ui_sound("UISndNewIncomingIMSession");
+			}
+		}
+	}
+	else if(session->isP2PSessionType())
+	{
+		if (LLAvatarTracker::instance().isBuddy(participant_id))
+		{
+			user_preferences = gSavedSettings.getString("NotificationFriendIMOptions");
+			if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundFriendIM") == TRUE))
+			{
+				make_ui_sound("UISndNewIncomingIMSession");
+			}
+		}
+		else
+		{
+			user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions");
+			if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNonFriendIM") == TRUE))
+			{
+				make_ui_sound("UISndNewIncomingIMSession");
+			}
+		}
+	}
+	else if(session->isAdHocSessionType())
+	{
+		user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions");
+		if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundConferenceIM") == TRUE))
+		{
+			make_ui_sound("UISndNewIncomingIMSession");
+		}
+	}
+	else if(session->isGroupSessionType())
+	{
+		user_preferences = gSavedSettings.getString("NotificationGroupChatOptions");
+		if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundGroupChatIM") == TRUE))
+		{
+			make_ui_sound("UISndNewIncomingIMSession");
+		}
+	}
 
-    // actions:
+	// actions:
 
     // 0. nothing - exit
-    if (("none" == user_preferences ||
+    if (("noaction" == user_preferences ||
     		ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status)
     	&& session_floater->isMessagePaneExpanded())
     {
@@ -261,57 +287,103 @@ void on_new_message(const LLSD& msg)
 				}
 			}
 		}
-        else
-        {
-            //If in DND mode, allow notification to be stored so upon DND exit
-            //useMostItrusiveIMNotification will be called to notify user a message exists
-            if(session_id.notNull()
-               && participant_id.notNull()
-		       && !session_floater->isShown())
-            {
-                LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
-	        }
-        }
-    }
+		else
+		{
+			store_dnd_message = true;
+		}
 
-    // 2. Flash line item
-    if ("openconversations" == user_preferences
-    		|| ON_TOP == conversations_floater_status
-    		|| ("toast" == user_preferences && ON_TOP != conversations_floater_status)
-    		|| ("flash" == user_preferences && CLOSED == conversations_floater_status))
-    {
-    	if(!LLMuteList::getInstance()->isMuted(participant_id))
-    	{
-    		im_box->flashConversationItemWidget(session_id, true);
-    	}
-    }
+	}
 
-    // 3. Flash FUI button
-    if (("toast" == user_preferences || "flash" == user_preferences) &&
-    		(CLOSED == conversations_floater_status
-    		    || NOT_ON_TOP == conversations_floater_status))
-    {
-    	if(!LLMuteList::getInstance()->isMuted(participant_id)
-            && !gAgent.isDoNotDisturb())
-    	{
-    		gToolBarView->flashCommand(LLCommandId("chat"), true);
-    	}
-    }
+	// 2. Flash line item
+	if ("openconversations" == user_preferences
+		|| ON_TOP == conversations_floater_status
+		|| ("toast" == user_preferences && ON_TOP != conversations_floater_status)
+		|| ("flash" == user_preferences && (CLOSED == conversations_floater_status
+				 	 	 	 	 	 	|| NOT_ON_TOP == conversations_floater_status))
+		|| is_dnd_msg)
+	{
+		if(!LLMuteList::getInstance()->isMuted(participant_id))
+		{
+			if(gAgent.isDoNotDisturb())
+			{
+				store_dnd_message = true;
+			}
+			else
+			{
+				if (is_dnd_msg && (ON_TOP == conversations_floater_status || 
+									NOT_ON_TOP == conversations_floater_status || 
+									CLOSED == conversations_floater_status))
+				{
+					im_box->highlightConversationItemWidget(session_id, true);
+				}
+				else
+				{
+					im_box->flashConversationItemWidget(session_id, true);
+				}
+			}
+		}
+	}
 
-    // 4. Toast
-    if ((("toast" == user_preferences) &&
-    		(CLOSED == conversations_floater_status
-    		    || NOT_ON_TOP == conversations_floater_status))
-    		    || !session_floater->isMessagePaneExpanded())
+	// 3. Flash FUI button
+	if (("toast" == user_preferences || "flash" == user_preferences) &&
+		(CLOSED == conversations_floater_status
+		|| NOT_ON_TOP == conversations_floater_status)
+		&& !is_session_focused
+		&& !is_dnd_msg) //prevent flashing FUI button because the conversation floater will have already opened
+	{
+		if(!LLMuteList::getInstance()->isMuted(participant_id))
+		{
+			if(!gAgent.isDoNotDisturb())
+			{
+				gToolBarView->flashCommand(LLCommandId("chat"), true, im_box->isMinimized());
+			}
+			else
+			{
+				store_dnd_message = true;
+			}
+		}
+	}
 
-    {
-        //Show IM toasts (upper right toasts)
-        // Skip toasting for system messages and for nearby chat
-        if(session_id.notNull() && participant_id.notNull())
-        {
-            LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
-        }
-    }
+	// 4. Toast
+	if ((("toast" == user_preferences) &&
+		(ON_TOP_AND_ITEM_IS_SELECTED != conversations_floater_status) &&
+		(!session_floater->isTornOff() || !LLFloater::isVisible(session_floater)))
+		|| !session_floater->isMessagePaneExpanded())
+
+	{
+		//Show IM toasts (upper right toasts)
+		// Skip toasting for system messages and for nearby chat
+		if(session_id.notNull() && participant_id.notNull())
+		{
+			if(!is_dnd_msg)
+			{
+				if(gAgent.isDoNotDisturb())
+				{
+					store_dnd_message = true;
+				}
+				else
+				{
+					LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+				}
+			}
+		}
+	}
+	if (store_dnd_message)
+	{
+		// If in DND mode, allow notification to be stored so upon DND exit 
+		// the user will be notified with some limitations (see 'is_dnd_msg' flag checks)
+		if(session_id.notNull()
+			&& participant_id.notNull()
+			&& !session_floater->isShown())
+		{
+			LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+		}
+	}
+}
+
+void on_new_message(const LLSD& msg)
+{
+	notify_of_message(msg, false);
 }
 
 LLIMModel::LLIMModel() 
@@ -2597,6 +2669,13 @@ void LLIMMgr::addMessage(
 		fixed_session_name = session_name;
 		name_is_setted = true;
 	}
+	bool skip_message = false;
+	if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
+	{
+		// Evaluate if we need to skip this message when that setting is true (default is false)
+		skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);	// Skip non friends...
+		skip_message &= !(other_participant_id == gAgentID);	// You are your best friend... Don't skip yourself
+	}
 
 	bool new_session = !hasSession(new_session_id);
 	if (new_session)
@@ -2608,6 +2687,12 @@ void LLIMMgr::addMessage(
 		}
 		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
 
+		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id);
+		skip_message &= !session->isGroupSessionType();			// Do not skip group chats...
+		if(skip_message)
+		{
+			gIMMgr->leaveSession(new_session_id);
+		}
 		// When we get a new IM, and if you are a god, display a bit
 		// of information about the source. This is to help liaisons
 		// when answering questions.
@@ -2648,23 +2733,13 @@ void LLIMMgr::addMessage(
         }
 	}
 
-	bool skip_message = false;
-	if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
-	{
-		// Evaluate if we need to skip this message when that setting is true (default is false)
-		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id);
-		skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);	// Skip non friends...
-		skip_message &= !session->isGroupSessionType();			// Do not skip group chats...
-		skip_message &= !(other_participant_id == gAgentID);	// You are your best friend... Don't skip yourself
-	}
-
 	if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
 	{
 		LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
 	}
 
 	// Open conversation floater if offline messages are present
-	if (is_offline_msg)
+	if (is_offline_msg && !skip_message)
     {
         LLFloaterReg::showInstance("im_container");
 	    LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->
@@ -2971,10 +3046,9 @@ void LLIMMgr::inviteToSession(
 	{
 		bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
 		bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
-		bool isRejectDoNotDisturb = (gAgent.isDoNotDisturb() && !hasSession(session_id));
-		if	(isRejectGroupCall || isRejectNonFriendCall || isRejectDoNotDisturb)
+		if	(isRejectGroupCall || isRejectNonFriendCall || gAgent.isDoNotDisturb())
 		{
-			if (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall)
+			if (gAgent.isDoNotDisturb() && !isRejectGroupCall && !isRejectNonFriendCall)
 			{
 				LLSD args;
 				addSystemMessage(session_id, "you_auto_rejected_call", args);
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 92f2d33073ec8ea029f7b9d5095f47d30cebca97..3c6974cf6d3a4eefbc5ba69cac47e50523ad1455 100755
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -70,11 +70,8 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 	mFilterSubString(p.substring),
 	mCurrentGeneration(0),
 	mFirstRequiredGeneration(0),
-	mFirstSuccessGeneration(0),
-	mFilterCount(0)
+	mFirstSuccessGeneration(0)
 {
-	mNextFilterGeneration = mCurrentGeneration + 1;
-
 	// copy mFilterOps into mDefaultFilterOps
 	markDefault();
 }
@@ -92,9 +89,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 		return passed_clipboard;
 	}
 
-	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
-
-	BOOL passed = (mFilterSubString.size() == 0 || string_offset != std::string::npos);
+	bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true);
 	passed = passed && checkAgainstFilterType(listener);
 	passed = passed && checkAgainstPermissions(listener);
 	passed = passed && checkAgainstFilterLinks(listener);
@@ -105,17 +100,12 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 
 bool LLInventoryFilter::check(const LLInventoryItem* item)
 {
-	std::string::size_type string_offset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
-
+	const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true);
 	const bool passed_filtertype = checkAgainstFilterType(item);
 	const bool passed_permissions = checkAgainstPermissions(item);
-	const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID());
-	const bool passed = (passed_filtertype 
-		&& passed_permissions
-		&& passed_clipboard 
-		&&	(mFilterSubString.size() == 0 || string_offset != std::string::npos));
+	const bool passed_clipboard = checkAgainstClipboard(item->getUUID());
 
-	return passed;
+	return passed_filtertype && passed_permissions && passed_clipboard && passed_string;
 }
 
 bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
@@ -439,7 +429,7 @@ void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
 		current_types = types;
 		if (more_bits_set && fewer_bits_set)
 		{
-			// neither less or more restrive, both simultaneously
+			// neither less or more restrictive, both simultaneously
 			// so we need to filter from scratch
 			setModified(FILTER_RESTART);
 		}
@@ -714,7 +704,7 @@ void LLInventoryFilter::resetDefault()
 void LLInventoryFilter::setModified(EFilterModified behavior)
 {
 	mFilterText.clear();
-	mCurrentGeneration = mNextFilterGeneration++;
+	mCurrentGeneration++;
 
 	if (mFilterModified == FILTER_NONE)
 	{
@@ -1021,21 +1011,19 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
 	return mFilterOps.mShowFolderState; 
 }
 
-void LLInventoryFilter::setFilterCount(S32 count) 
-{ 
-	mFilterCount = count; 
-}
-S32 LLInventoryFilter::getFilterCount() const
+bool LLInventoryFilter::isTimedOut()
 {
-	return mFilterCount;
+	return mFilterTime.hasExpired();
 }
 
-void LLInventoryFilter::decrementFilterCount() 
-{ 
-	mFilterCount--; 
+void LLInventoryFilter::resetTime(S32 timeout)
+{
+	mFilterTime.reset();
+    F32 time_in_sec = (F32)(timeout)/1000.0;
+	mFilterTime.setTimerExpirySec(time_in_sec);
 }
 
-S32 LLInventoryFilter::getCurrentGeneration() const 
+S32 LLInventoryFilter::getCurrentGeneration() const
 { 
 	return mCurrentGeneration;
 }
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 4912b5ca9162ed1c128f09137b6faf4b62ea31f3..ce516af0b93584d82e674042bda95b6cb8ae13be 100755
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -215,12 +215,11 @@ public:
 	void 				setModified(EFilterModified behavior = FILTER_RESTART);
 
 	// +-------------------------------------------------------------------+
-	// + Count
+	// + Time
 	// +-------------------------------------------------------------------+
-	void 				setFilterCount(S32 count);
-	S32 				getFilterCount() const;
-	void 				decrementFilterCount();
-
+	void 				resetTime(S32 timeout);
+    bool                isTimedOut();
+    
 	// +-------------------------------------------------------------------+
 	// + Default
 	// +-------------------------------------------------------------------+
@@ -262,13 +261,15 @@ private:
 	const std::string		mName;
 
 	S32						mCurrentGeneration;
+    // The following makes checking for pass/no pass possible even if the item is not checked against the current generation
+    // Any item that *did not pass* the "required generation" will *not pass* the current one
+    // Any item that *passes* the "success generation" will *pass* the current one
 	S32						mFirstRequiredGeneration;
 	S32						mFirstSuccessGeneration;
-	S32						mNextFilterGeneration;
 
-	S32						mFilterCount;
 	EFilterModified 		mFilterModified;
-
+	LLTimer                 mFilterTime;
+    
 	std::string 			mFilterText;
 	std::string 			mEmptyLookupMessage;
 };
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index cf1fd4c0d08d43778c1de8930eb6dbc7210b803a..e5b9e11d48d4c017becb103f8cd6d871075ad066 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -192,7 +192,7 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
     p.show_item_link_overlays = mShowItemLinkOverlays;
     p.root = NULL;
     p.options_menu = "menu_inventory.xml";
-	
+
     return LLUICtrlFactory::create<LLFolderView>(p);
 }
 
@@ -396,6 +396,7 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
 	return getFilter().getShowFolderState();
 }
 
+// Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849)
 void LLInventoryPanel::modelChanged(U32 mask)
 {
 	static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 2d7454b636b2254b512c3907ff9debf80285fc26..90b169ecd3ab3332049fc532c2ac03f853e2792f 100755
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -25,7 +25,7 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-
+#include "llfloaterconversationpreview.h"
 #include "llagent.h"
 #include "llagentui.h"
 #include "llavatarnamecache.h"
@@ -206,6 +206,7 @@ private:
 };
 
 LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
+LLLoadHistoryThread::load_end_signal_t * LLLoadHistoryThread::mLoadEndSignal = NULL;
 
 //static
 std::string LLLogChat::makeLogFileName(std::string filename)
@@ -336,75 +337,83 @@ void LLLogChat::saveHistory(const std::string& filename,
 void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
 {
 	if (file_name.empty())
-	{
-		llwarns << "Session name is Empty!" << llendl;
-		return ;
-	}
-
-	bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
+				{
+					LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL;
+					return ;
+				}
 
-	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
-	if (!fptr)
-	{
-		fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
-		if (!fptr)
-		{
-			return;						//No previous conversation with this name.
-		}
-	}
- 
-	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
-	char *bptr;
-	S32 len;
-	bool firstline = TRUE;
+				bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
 
-	if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END))
-	{	//We need to load the whole historyFile or it's smaller than recall size, so get it all.
-		firstline = FALSE;
-		if (fseek(fptr, 0, SEEK_SET))
-		{
-			fclose(fptr);
-			return;
-		}
-	}
+				LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
+				if (!fptr)
+				{
+					fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+					if (!fptr)
+					{
+						return;						//No previous conversation with this name.
+					}
+				}
 
-	while (fgets(buffer, LOG_RECALL_SIZE, fptr)  && !feof(fptr)) 
-	{
-		len = strlen(buffer) - 1;		/*Flawfinder: ignore*/
-		for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--)	*bptr='\0';
-		
-		if (firstline)
-		{
-			firstline = FALSE;
-			continue;
-		}
+				char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
+				char *bptr;
+				S32 len;
+				bool firstline = TRUE;
+
+				if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END))
+				{	//We need to load the whole historyFile or it's smaller than recall size, so get it all.
+					firstline = FALSE;
+					if (fseek(fptr, 0, SEEK_SET))
+					{
+						fclose(fptr);
+						return;
+					}
+				}
+			while (fgets(buffer, LOG_RECALL_SIZE, fptr)  && !feof(fptr))
+				{
+					len = strlen(buffer) - 1;		/*Flawfinder: ignore*/
+					for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--)	*bptr='\0';
+
+					if (firstline)
+					{
+						firstline = FALSE;
+						continue;
+					}
+
+					std::string line(buffer);
+
+					//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
+					if (' ' == line[0])
+					{
+						line.erase(0, MULTI_LINE_PREFIX.length());
+						append_to_last_message(messages, '\n' + line);
+					}
+					else if (0 == len && ('\n' == line[0] || '\r' == line[0]))
+					{
+						//to support old format's multilined messages with new lines used to divide paragraphs
+						append_to_last_message(messages, line);
+					}
+					else
+					{
+						LLSD item;
+						if (!LLChatLogParser::parse(line, item, load_params))
+						{
+							item[LL_IM_TEXT] = line;
+						}
+						messages.push_back(item);
+					}
+				}
+				fclose(fptr);
 
-		std::string line(buffer);
 
-		//updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
-		if (' ' == line[0])
-		{
-			line.erase(0, MULTI_LINE_PREFIX.length());
-			append_to_last_message(messages, '\n' + line);
-		}
-		else if (0 == len && ('\n' == line[0] || '\r' == line[0]))
-		{
-			//to support old format's multilined messages with new lines used to divide paragraphs
-			append_to_last_message(messages, line);
-		}
-		else
-		{
-			LLSD item;
-			if (!LLChatLogParser::parse(line, item, load_params))
-			{
-				item[LL_IM_TEXT] = line;
-			}
-			messages.push_back(item);
-		}
-	}
-	fclose(fptr);
 }
 
+void LLLogChat::startChatHistoryThread(const std::string& file_name, const LLSD& load_params)
+{
+
+	LLLoadHistoryThread* mThread = new LLLoadHistoryThread();
+	mThread->start();
+	mThread->setHistoryParams(file_name, load_params);
+}
 // static
 std::string LLLogChat::oldLogFileName(std::string filename)
 {
@@ -461,6 +470,13 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string
 		LLFILE * filep = LLFile::fopen(fullname, "rb");
 		if (NULL != filep)
 		{
+			if(makeLogFileName("chat")== fullname)
+			{
+				//Add Nearby chat history to the list of transcriptions
+				list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
+				LLFile::close(filep);
+				return;
+			}
 			char buffer[LOG_RECALL_SIZE];
 
 			fseek(filep, 0, SEEK_END);			// seek to end of file
@@ -631,7 +647,7 @@ void LLLogChat::deleteTranscripts()
 }
 
 // static
-bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id)
+bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group)
 {
 	std::vector<std::string> list_of_transcriptions;
 	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
@@ -641,20 +657,53 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id)
 		LLAvatarName avatar_name;
 		LLAvatarNameCache::get(avatar_id, &avatar_name);
 		std::string avatar_user_name = avatar_name.getAccountName();
-		std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
-
-		BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+		if(!is_group)
 		{
-			if (std::string::npos != transcript_file_name.find(avatar_user_name))
+			std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
+			BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
 			{
-				return true;
+				if (std::string::npos != transcript_file_name.find(avatar_user_name))
+				{
+					return true;
+				}
 			}
 		}
+		else
+		{
+			std::string file_name;
+			gCacheName->getGroupName(avatar_id, file_name);
+			file_name = makeLogFileName(file_name);
+			BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+			{
+				if (transcript_file_name == file_name)
+				{
+					return true;
+				}
+			}
+		}
+
 	}
 
 	return false;
 }
 
+bool LLLogChat::isNearbyTranscriptExist()
+{
+	std::vector<std::string> list_of_transcriptions;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+
+	std::string file_name;
+	file_name = makeLogFileName("chat");
+	BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+	{
+	   	if (transcript_file_name == file_name)
+	   	{
+			return true;
+		 }
+	}
+	return false;
+}
+
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 //which are more strict by its nature (only firstname and secondname)
 //Example, an object's name can be written like "Object <actual_object's_name>"
@@ -795,3 +844,116 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
 	return true;  //parsed name and message text, maybe have a timestamp too
 }
+
+
+
+	LLLoadHistoryThread::LLLoadHistoryThread() : LLThread("load chat history")
+ 	{
+		mNewLoad = false;
+	}
+
+	void LLLoadHistoryThread::run()
+	{
+		while (!LLApp::isQuitting())
+			{
+			    if(mNewLoad)
+				{
+					loadHistory(mFileName,mMessages,mLoadParams);
+					shutdown();
+				}
+			}
+	}
+	void LLLoadHistoryThread::setHistoryParams(const std::string& file_name, const LLSD& load_params)
+	{
+		mFileName = file_name;
+		mLoadParams = load_params;
+		mNewLoad = true;
+	}
+	void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
+	{
+
+		if (file_name.empty())
+			{
+			LL_WARNS("LLLogChat::loadHistory") << "Session name is Empty!" << LL_ENDL;
+				return ;
+			}
+
+			bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
+
+			LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
+			if (!fptr)
+			{
+				fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+				if (!fptr)
+				{
+					mNewLoad = false;
+					(*mLoadEndSignal)(messages, file_name);
+					return;						//No previous conversation with this name.
+				}
+			}
+
+			char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
+			char *bptr;
+			S32 len;
+			bool firstline = TRUE;
+
+			if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END))
+			{	//We need to load the whole historyFile or it's smaller than recall size, so get it all.
+				firstline = FALSE;
+				if (fseek(fptr, 0, SEEK_SET))
+				{
+					fclose(fptr);
+					mNewLoad = false;
+					(*mLoadEndSignal)(messages, file_name);
+					return;
+				}
+			}
+		while (fgets(buffer, LOG_RECALL_SIZE, fptr)  && !feof(fptr))
+			{
+				len = strlen(buffer) - 1;		/*Flawfinder: ignore*/
+				for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--)	*bptr='\0';
+
+				if (firstline)
+				{
+					firstline = FALSE;
+					continue;
+				}
+
+				std::string line(buffer);
+
+				//updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
+				if (' ' == line[0])
+				{
+					line.erase(0, MULTI_LINE_PREFIX.length());
+					append_to_last_message(messages, '\n' + line);
+				}
+				else if (0 == len && ('\n' == line[0] || '\r' == line[0]))
+				{
+					//to support old format's multilined messages with new lines used to divide paragraphs
+					append_to_last_message(messages, line);
+				}
+				else
+				{
+					LLSD item;
+					if (!LLChatLogParser::parse(line, item, load_params))
+					{
+						item[LL_IM_TEXT] = line;
+					}
+					messages.push_back(item);
+				}
+			}
+			fclose(fptr);
+			mNewLoad = false;
+			(*mLoadEndSignal)(messages, file_name);
+	}
+
+	//static
+	boost::signals2::connection LLLoadHistoryThread::setLoadEndSignal(const load_end_signal_t::slot_type& cb)
+	{
+		if (NULL == mLoadEndSignal)
+		{
+			mLoadEndSignal = new load_end_signal_t();
+		}
+
+		return mLoadEndSignal->connect(cb);
+	}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index e819f00dd9c5f6e3cea756a24ddcc3c521fe2995..acee99afa2c1ee723ee958d963826555d1da62a7 100755
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -28,6 +28,24 @@
 #define LL_LLLOGCHAT_H
 
 class LLChat;
+class LLLoadHistoryThread : public LLThread
+{
+private:
+	std::string mFileName;
+	std::list<LLSD> mMessages;
+	LLSD mLoadParams;
+	bool mNewLoad;
+public:
+	LLLoadHistoryThread();
+
+	void setHistoryParams(const std::string& file_name, const LLSD& load_params);
+	virtual void loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params);
+    virtual void run();
+
+   typedef boost::signals2::signal<void (std::list<LLSD>& messages,const std::string& file_name)> load_end_signal_t;
+   static load_end_signal_t * mLoadEndSignal;
+   static boost::signals2::connection setLoadEndSignal(const load_end_signal_t::slot_type& cb);
+};
 
 class LLLogChat
 {
@@ -39,6 +57,7 @@ public:
 		LOG_LLSD,
 		LOG_END
 	};
+
 	static std::string timestamp(bool withdate = false);
 	static std::string makeLogFileName(std::string(filename));
 	/**
@@ -54,6 +73,7 @@ public:
 	static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
 
 	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+	static void startChatHistoryThread(const std::string& file_name, const LLSD& load_params);
 
 	typedef boost::signals2::signal<void ()> save_history_signal_t;
 	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
@@ -67,7 +87,8 @@ public:
 		std::vector<std::string>& listOfFilesToMove);
 
 	static void deleteTranscripts();
-	static bool isTranscriptExist(const LLUUID& avatar_id);
+	static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false);
+	static bool isNearbyTranscriptExist();
 
 private:
 	static std::string cleanFileName(std::string filename);
@@ -126,6 +147,7 @@ protected:
 	virtual ~LLChatLogParser() {};
 };
 
+
 // LLSD map lookup constants
 extern const std::string LL_IM_TIME; //("time");
 extern const std::string LL_IM_TEXT; //("message");
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d79f1040bba740c385ecbf13e72e446df852f073..4cbdfde8689b59c9b1919d3ac12ee3ebc2398691 100755
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -1376,74 +1376,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 		BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
 		projected_mouse -= snap_plane_center;
 
-		S32 snap_plane = 0;
-
-		F32 dot = cam_to_snap_plane * constraint_axis;
-		if (llabs(dot) < 0.01f)
-		{
-			// looking at ring edge on, project onto view plane and check if mouse is past ring
-			getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
-			projected_mouse -= snap_plane_center;
-			dot = projected_mouse * constraint_axis;
-			if (projected_mouse * constraint_axis > 0)
-			{
-				snap_plane = 1;
-			}
-			projected_mouse -= dot * constraint_axis;
-		}
-		else if (dot > 0.f)
-		{
-			// look for mouse position outside and in front of snap circle
-			if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
-			{
-				snap_plane = 1;
-			}
-		}
-		else
-		{
-			// look for mouse position inside or in back of snap circle
-			if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
-			{
-				snap_plane = 1;
-			}
-		}
-
-		if (snap_plane == 0)
-		{
-			// try other plane
-			snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
-			if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
-			{
-				cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
-			}
-			else
-			{
-				cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
-				cam_to_snap_plane.normVec();
-			}
-
-			hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
-			projected_mouse -= snap_plane_center;
-
-			dot = cam_to_snap_plane * constraint_axis;
+		if (gSavedSettings.getBOOL("SnapEnabled")) {
+			S32 snap_plane = 0;
+	
+			F32 dot = cam_to_snap_plane * constraint_axis;
 			if (llabs(dot) < 0.01f)
 			{
 				// looking at ring edge on, project onto view plane and check if mouse is past ring
 				getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
 				projected_mouse -= snap_plane_center;
 				dot = projected_mouse * constraint_axis;
-				if (projected_mouse * constraint_axis < 0)
+				if (projected_mouse * constraint_axis > 0)
 				{
-					snap_plane = 2;
+					snap_plane = 1;
 				}
 				projected_mouse -= dot * constraint_axis;
 			}
-			else if (dot < 0.f)
+			else if (dot > 0.f)
 			{
 				// look for mouse position outside and in front of snap circle
 				if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
 				{
-					snap_plane = 2;
+					snap_plane = 1;
 				}
 			}
 			else
@@ -1451,78 +1405,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 				// look for mouse position inside or in back of snap circle
 				if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
 				{
-					snap_plane = 2;
+					snap_plane = 1;
 				}
 			}
-		}
-
-		if (snap_plane > 0)
-		{
-			LLVector3 cam_at_axis;
-			if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
-			{
-				cam_at_axis.setVec(1.f, 0.f, 0.f);
-			}
-			else
-			{
-				cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
-				cam_at_axis.normVec();
-			}
-
-			// first, project mouse onto screen plane at point tangent to rotation radius. 
-			getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
-			// project that point onto rotation plane
-			projected_mouse -= snap_plane_center;
-			projected_mouse -= projected_vec(projected_mouse, constraint_axis);
-
-			F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
-			F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
-			if (llabs(mouse_lateral_dist) > 0.01f)
-			{
-				mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - 
-									(mouse_lateral_dist * mouse_lateral_dist));
-			}
-			LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
-			projected_mouse -= mouse_depth * projected_camera_at;
-
-			if (!mInSnapRegime)
+	
+			if (snap_plane == 0)
 			{
-				mSmoothRotate = TRUE;
+				// try other plane
+				snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
+				if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+				{
+					cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
+				}
+				else
+				{
+					cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+					cam_to_snap_plane.normVec();
+				}
+	
+				hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
+				projected_mouse -= snap_plane_center;
+	
+				dot = cam_to_snap_plane * constraint_axis;
+				if (llabs(dot) < 0.01f)
+				{
+					// looking at ring edge on, project onto view plane and check if mouse is past ring
+					getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
+					projected_mouse -= snap_plane_center;
+					dot = projected_mouse * constraint_axis;
+					if (projected_mouse * constraint_axis < 0)
+					{
+						snap_plane = 2;
+					}
+					projected_mouse -= dot * constraint_axis;
+				}
+				else if (dot < 0.f)
+				{
+					// look for mouse position outside and in front of snap circle
+					if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
+					{
+						snap_plane = 2;
+					}
+				}
+				else
+				{
+					// look for mouse position inside or in back of snap circle
+					if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
+					{
+						snap_plane = 2;
+					}
+				}
 			}
-			mInSnapRegime = TRUE;
-			// 0 to 360 deg
-			F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
 			
-			F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
-			//fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
-
-			LLVector3 object_axis;
-			getObjectAxisClosestToMouse(object_axis);
-			object_axis = object_axis * first_object_node->mSavedRotation;
-
-			// project onto constraint plane
-			object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
-			object_axis.normVec();
-
-			if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+			if (snap_plane > 0)
 			{
-				F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
-				angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				LLVector3 cam_at_axis;
+				if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+				{
+					cam_at_axis.setVec(1.f, 0.f, 0.f);
+				}
+				else
+				{
+					cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+					cam_at_axis.normVec();
+				}
+	
+				// first, project mouse onto screen plane at point tangent to rotation radius. 
+				getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
+				// project that point onto rotation plane
+				projected_mouse -= snap_plane_center;
+				projected_mouse -= projected_vec(projected_mouse, constraint_axis);
+	
+				F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
+				F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
+				if (llabs(mouse_lateral_dist) > 0.01f)
+				{
+					mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - 
+										(mouse_lateral_dist * mouse_lateral_dist));
+				}
+				LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
+				projected_mouse -= mouse_depth * projected_camera_at;
+	
+				if (!mInSnapRegime)
+				{
+					mSmoothRotate = TRUE;
+				}
+				mInSnapRegime = TRUE;
+				// 0 to 360 deg
+				F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
+				
+				F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
+				//fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
+	
+				LLVector3 object_axis;
+				getObjectAxisClosestToMouse(object_axis);
+				object_axis = object_axis * first_object_node->mSavedRotation;
+	
+				// project onto constraint plane
+				object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
+				object_axis.normVec();
+	
+				if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+				{
+					F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
+					angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				}
+				else
+				{
+					angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				}
+				return LLQuaternion( -angle, constraint_axis );
 			}
 			else
 			{
-				angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				if (mInSnapRegime)
+				{
+					mSmoothRotate = TRUE;
+				}
+				mInSnapRegime = FALSE;
 			}
-			return LLQuaternion( -angle, constraint_axis );
 		}
-		else
-		{
+		else {
 			if (mInSnapRegime)
 			{
 				mSmoothRotate = TRUE;
 			}
 			mInSnapRegime = FALSE;
-
+		}
+		
+		if (!mInSnapRegime)
+		{
 			LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis;
 			up_from_axis.normVec();
 			LLVector3 cur_intersection;
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index 7aabf7d09e03a9586a2516fd64b3bf30665f97a5..53fd898ea4ee09b1e694945babb0fa48724311ef 100755
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -44,6 +44,7 @@ public:
 protected:
 	bool writeNotifications(const LLSD& pNotificationData) const;
 	bool readNotifications(LLSD& pNotificationData) const;
+	void setFileName(std::string pFileName) {mFileName = pFileName;}
 
 	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const;
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index a85335f1ba9c0a3a2e5ccd8c1f05b016a78df934..4ca961c1f908a6414822831e7d4be083ab253ebe 100755
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -83,13 +83,6 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 	if (notification->canLogToChat())
 	{
 		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
-
-		// don't show toast if Nearby Chat is opened
-		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
-		if (nearby_chat->isChatVisible())
-		{
-			return false;
-		}
 	}
 
 	std::string session_name = notification->getPayload()["SESSION_NAME"];
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index cfdac11d26b6bfb0ccbf04c4fbd042121fa5643f..fdcd1f5ebb1fa8a8339866ec504fe934894151d2 100755
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1101,27 +1101,61 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
 }
 
 void LLPanelGroupMembersSubTab::handleEjectMembers()
-{
-	//send down an eject message
-	uuid_vec_t selected_members;
-
+{	
 	std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
 	if (selection.empty()) return;
-
-	std::vector<LLScrollListItem*>::iterator itor;
-	for (itor = selection.begin() ; 
-		 itor != selection.end(); ++itor)
+	
+	S32 selection_count = selection.size();
+	if (selection_count == 1)
 	{
-		LLUUID member_id = (*itor)->getUUID();
-		selected_members.push_back( member_id );
+		LLSD args;
+		LLUUID selected_avatar = mMembersList->getValue().asUUID();
+		std::string fullname = LLSLURL("agent", selected_avatar, "inspect").getSLURLString();
+		args["AVATAR_NAME"] = fullname;
+		LLSD payload;
+		LLNotificationsUtil::add("EjectGroupMemberWarning",
+								 args,
+								 payload,
+								 boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
 	}
+	else
+	{
+		LLSD args;
+		args["COUNT"] = llformat("%d", selection_count);
+		LLSD payload;
+		LLNotificationsUtil::add("EjectGroupMembersWarning",
+								 args,
+								 payload,
+								 boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
+	}
+}
 
-	mMembersList->deleteSelectedItems();
-
-	sendEjectNotifications(mGroupID, selected_members);
-
-	LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID,
-									 selected_members);
+bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (0 == option) // Eject button
+	{
+		//send down an eject message
+		uuid_vec_t selected_members;
+		
+		std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
+		if (selection.empty()) return false;
+		
+		std::vector<LLScrollListItem*>::iterator itor;
+		for (itor = selection.begin() ;
+			 itor != selection.end(); ++itor)
+		{
+			LLUUID member_id = (*itor)->getUUID();
+			selected_members.push_back( member_id );
+		}
+		
+		mMembersList->deleteSelectedItems();
+		
+		sendEjectNotifications(mGroupID, selected_members);
+		
+		LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members);
+	}
+	return false;
 }
 
 void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members)
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 78bb3c57a16a282c73868897305820fb5341b0a5..0cf272f3ee05de0fe7d3023a39ab3a2bb410b64a 100755
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -167,6 +167,7 @@ public:
 	static void onEjectMembers(void*);
 	void handleEjectMembers();
 	void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members);
+	bool handleEjectCallback(const LLSD& notification, const LLSD& response);
 
 	static void onRoleCheck(LLUICtrl* check, void* user_data);
 	void handleRoleCheck(const LLUUID& role_id,
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index bcb90bcb56662d219b2453909d61a81588a6437f..911ecaad9dbdc0a3c0dbc22cb7d49ccc7e33b380 100755
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -82,10 +82,6 @@ const S32 MAX_PASSWORD = 16;
 LLPanelLogin *LLPanelLogin::sInstance = NULL;
 BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
 
-// Helper for converting a user name into the canonical "Firstname Lastname" form.
-// For new accounts without a last name "Resident" is added as a last name.
-static std::string canonicalize_username(const std::string& name);
-
 class LLLoginRefreshHandler : public LLCommandHandler
 {
 public:
@@ -266,7 +262,6 @@ void LLPanelLogin::addFavoritesToStartLocation()
 
 	// Load favorites into the combo.
 	std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
-	std::string canonical_user_name = canonicalize_username(user_defined_name);
 	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
 	LLSD fav_llsd;
 	llifstream file;
@@ -279,7 +274,7 @@ void LLPanelLogin::addFavoritesToStartLocation()
 		// The account name in stored_favorites.xml has Resident last name even if user has
 		// a single word account name, so it can be compared case-insensitive with the
 		// user defined "firstname lastname".
-		S32 res = LLStringUtil::compareInsensitive(canonical_user_name, iter->first);
+		S32 res = LLStringUtil::compareInsensitive(user_defined_name, iter->first);
 		if (res != 0)
 		{
 			lldebugs << "Skipping favorites for " << iter->first << llendl;
@@ -1012,29 +1007,3 @@ void LLPanelLogin::onLocationSLURL()
 
 	LLStartUp::setStartSLURL(location); // calls onUpdateStartSLURL, above 
 }
-
-
-std::string canonicalize_username(const std::string& name)
-{
-	std::string cname = name;
-	LLStringUtil::trim(cname);
-
-	// determine if the username is a first/last form or not.
-	size_t separator_index = cname.find_first_of(" ._");
-	std::string first = cname.substr(0, separator_index);
-	std::string last;
-	if (separator_index != cname.npos)
-	{
-		last = cname.substr(separator_index+1, cname.npos);
-		LLStringUtil::trim(last);
-	}
-	else
-	{
-		// ...on Linden grids, single username users as considered to have
-		// last name "Resident"
-		last = "Resident";
-	}
-
-	// Username in traditional "firstname lastname" form.
-	return first + ' ' + last;
-}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index d6535c88e927f830850dcbad957a03e16abdd595..53deded2f23cc8594e3ab57b4924bbb3ce47d152 100755
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -130,6 +130,8 @@ BOOL LLPanelMainInventory::postBuild()
 	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
 	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
 	
+    mCounterCtrl = getChild<LLUICtrl>("ItemcountText");
+    
 	//panel->getFilter().markDefault();
 
 	// Set up the default inv. panel/filter settings.
@@ -566,7 +568,7 @@ void LLPanelMainInventory::draw()
 void LLPanelMainInventory::updateItemcountText()
 {
 	// *TODO: Calling setlocale() on each frame may be inefficient.
-	LLLocale locale(LLStringUtil::getLocale());
+	//LLLocale locale(LLStringUtil::getLocale());
 	std::string item_count_string;
 	LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
 
@@ -589,8 +591,7 @@ void LLPanelMainInventory::updateItemcountText()
 		text = getString("ItemcountUnknown");
 	}
 	
-	// *TODO: Cache the LLUICtrl* for the ItemcountText control
-	getChild<LLUICtrl>("ItemcountText")->setValue(text);
+    mCounterCtrl->setValue(text);
 }
 
 void LLPanelMainInventory::onFocusReceived()
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 899931aa89778182194223d8fe5407f913c1a774..394b004e209ffafb95382edc148d1b2459da5775 100755
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -121,6 +121,7 @@ private:
 
 	LLFilterEditor*				mFilterEditor;
 	LLTabContainer*				mFilterTabs;
+    LLUICtrl*                   mCounterCtrl;
 	LLHandle<LLFloater>			mFinderHandle;
 	LLInventoryPanel*			mActivePanel;
 	bool						mResortActivePanel;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 4138558bad150b4414f45eceb37845ab78a49c6c..d7c634d6194678b84bfb03f3bf19211ebe7422ed 100755
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -76,6 +76,8 @@ static const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars
 
 static const std::string COLLAPSED_BY_USER  = "collapsed_by_user";
 
+extern S32 gMaxAgentGroups;
+
 /** Comparator for comparing avatar items by last interaction date */
 class LLAvatarItemRecentComparator : public LLAvatarItemComparator
 {
@@ -808,6 +810,8 @@ void LLPanelPeople::updateButtons()
 
 		LLPanel* groups_panel = mTabContainer->getCurrentPanel();
 		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
+		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
+		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.count())));
 	}
 	else
 	{
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index e2e70067737035f532ae343562829e84a3361e7d..5acc98904ba6b4589ec49599c8cbf6d087dd0a5d 100755
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -36,6 +36,8 @@
 #include "lltabcontainer.h"
 #include "llviewercontrol.h"
 #include "llviewernetwork.h"
+#include "llmutelist.h"
+#include "llpanelblockedlist.h"
 
 static const std::string PANEL_PICKS = "panel_picks";
 
@@ -137,6 +139,12 @@ public:
 			return true;
 		}
 
+		if (verb == "removefriend")
+		{
+			LLAvatarActions::removeFriendDialog(avatar_id);
+			return true;
+		}
+
 		if (verb == "mute")
 		{
 			if (! LLAvatarActions::isBlocked(avatar_id))
@@ -155,6 +163,18 @@ public:
 			return true;
 		}
 
+		if (verb == "block")
+		{
+			if (params.size() > 2)
+			{
+				const std::string object_name = params[2].asString();
+				LLMute mute(avatar_id, object_name, LLMute::OBJECT);
+				LLMuteList::getInstance()->add(mute);
+				LLPanelBlockedList::showPanelAndSelect(mute.mID);
+			}
+			return true;
+		}
+
 		return false;
 	}
 };
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 666f10df964ae036a076594ff40117b903704796..076c3e0235b9b22bb7c25eefcbccd1f321b47813 100755
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -38,7 +38,8 @@
 
 LLPersistentNotificationStorage::LLPersistentNotificationStorage()
 	: LLSingleton<LLPersistentNotificationStorage>()
-	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"))
+	, LLNotificationStorage("")
+	, mLoaded(false)
 {
 }
 
@@ -89,8 +90,13 @@ void LLPersistentNotificationStorage::loadNotifications()
 
 	LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL;
 
-	LLNotifications::instance().getChannel("Persistent")->
-		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+	if (mLoaded)
+	{
+		LL_INFOS("LLPersistentNotificationStorage") << "notifications already loaded, exiting" << LL_ENDL;
+		return;
+	}
+
+	mLoaded = true;
 
 	LLSD input;
 	if (!readNotifications(input) ||input.isUndefined())
@@ -135,8 +141,20 @@ void LLPersistentNotificationStorage::loadNotifications()
 	LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
 }
 
+void LLPersistentNotificationStorage::initialize()
+{
+	setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+	LLNotifications::instance().getChannel("Persistent")->
+		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+}
+
 bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
 {
+	// In case we received channel changed signal but haven't yet loaded notifications, do it
+	if (!mLoaded)
+	{
+		loadNotifications();
+	}
 	// we ignore "load" messages, but rewrite the persistence file on any other
 	const std::string sigtype = payload["sigtype"].asString();
 	if ("load" != sigtype)
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
index 98a825d2c139148807cd79a36225703954ad380e..bf0306380e7bd1f3c9658222451d4ea5fa48659d 100755
--- a/indra/newview/llpersistentnotificationstorage.h
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -53,10 +53,13 @@ public:
 	void saveNotifications();
 	void loadNotifications();
 
+	void initialize();
+
 protected:
 
 private:
 	bool onPersistentChannelChanged(const LLSD& payload);
+	bool mLoaded;
 };
 
 #endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 968a912ea28c51825c51bddd1df00b3bf27618fd..e533be7f246da3ab3393f3412eaab438afdf1f3e 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -86,6 +86,7 @@
 #include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llappviewer.h"
+#include "llfloatergotoline.h"
 
 const std::string HELLO_LSL =
 	"default\n"
@@ -193,12 +194,17 @@ private:
 	LLScriptEdCore* mEditorCore;
 
 	static LLFloaterScriptSearch*	sInstance;
+
+protected:
+	LLLineEditor*			mSearchBox;
+        void onSearchBoxCommit();
 };
 
 LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL;
 
 LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
 :	LLFloater(LLSD()),
+	mSearchBox(NULL),
 	mEditorCore(editor_core)
 {
 	buildFromFile("floater_script_search.xml");
@@ -221,6 +227,9 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
 
 BOOL LLFloaterScriptSearch::postBuild()
 {
+	mSearchBox = getChild<LLLineEditor>("search_text");
+	mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this));
+	mSearchBox->setCommitOnFocusLost(FALSE);
 	childSetAction("search_btn", onBtnSearch,this);
 	childSetAction("replace_btn", onBtnReplace,this);
 	childSetAction("replace_all_btn", onBtnReplaceAll,this);
@@ -315,6 +324,15 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)
 	return FALSE;
 }
 
+void LLFloaterScriptSearch::onSearchBoxCommit()
+{
+	if (mEditorCore && mEditorCore->mEditor)
+	{
+		LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text");
+		mEditorCore->mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get());
+	}
+}
+
 /// ---------------------------------------------------------------------------
 /// LLScriptEdCore
 /// ---------------------------------------------------------------------------
@@ -503,6 +521,9 @@ void LLScriptEdCore::initMenu()
 	menuItem = getChild<LLMenuItemCallGL>("Search / Replace...");
 	menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this));
 
+	menuItem = getChild<LLMenuItemCallGL>("Go to line...");
+	menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this));
+
 	menuItem = getChild<LLMenuItemCallGL>("Help...");
 	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
 
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 7563cecd9dba8b979f34e405d660d0a1e5500c95..9fb0a4fb63b9a838d88385a0f000c0a310bae84a 100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -34,6 +34,7 @@
 #include "llcombobox.h"
 #include "lliconctrl.h"
 #include "llframetimer.h"
+#include "llfloatergotoline.h"
 
 class LLLiveLSLFile;
 class LLMessageSystem;
@@ -49,6 +50,7 @@ class LLKeywordToken;
 class LLVFS;
 class LLViewerInventoryItem;
 class LLScriptEdContainer;
+class LLFloaterGotoLine;
 
 // Inner, implementation class.  LLPreviewScript and LLLiveLSLEditor each own one of these.
 class LLScriptEdCore : public LLPanel
@@ -58,6 +60,7 @@ class LLScriptEdCore : public LLPanel
 	friend class LLLiveLSLEditor;
 	friend class LLFloaterScriptSearch;
 	friend class LLScriptEdContainer;
+	friend class LLFloaterGotoLine;
 
 protected:
 	// Supposed to be invoked only by the container.
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index cff3a7e02ac2491d5fed9e21d7c6175f9a14f988..67a76460a71fcd0e6be3497946bc81c08ca31c76 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -51,6 +51,7 @@
 #include "lllandmark.h"
 #include "llcachename.h"
 #include "lldir.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llerrorcontrol.h"
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
@@ -68,6 +69,7 @@
 #include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
+#include "llpersistentnotificationstorage.h"
 #include "llteleporthistory.h"
 #include "llregionhandle.h"
 #include "llsd.h"
@@ -900,6 +902,10 @@ bool idle_startup()
 		gDirUtilp->setLindenUserDir(userid);
 		LLFile::mkdir(gDirUtilp->getLindenUserDir());
 
+		// As soon as directories are ready initialize notification storages
+		LLPersistentNotificationStorage::getInstance()->initialize();
+		LLDoNotDisturbNotificationStorage::getInstance()->initialize();
+
 		// Set PerAccountSettingsFile to the default value.
 		gSavedSettings.setString("PerAccountSettingsFile",
 			gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, 
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index e92bd766ca7f60b442178a37cff4b257dd289eee..1a3add2bfb1ded9b61ee32f466ef8d31939d24f9 100755
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -423,9 +423,18 @@ void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
 void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
 {
 	LLUUID id = item->getID();
-	removeItemByID(id);
+	
 	if(mChannel)
+	{
+		// removeItemByID() is invoked from killToastByNotificationID() and item will removed;
 		mChannel->killToastByNotificationID(id);
+	}
+	else
+	{
+		// removeItemByID() should be called one time for each item to remove it from notification well
+		removeItemByID(id);
+	}
+
 }
 
 void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index 75e6e3d13a4a3b07e24e6fa1b40d0fe6042442df..09ab31df369af8e85c346bd2ba993b625f954f01 100755
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -28,6 +28,7 @@
 #include "lltoastimpanel.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llfloaterreg.h"
 #include "llgroupactions.h"
 #include "llgroupiconctrl.h"
@@ -61,6 +62,15 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif
 	style_params.font.name(font_name);
 	style_params.font.size(font_size);
 	
+	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(p.session_id);
+	mIsGroupMsg = (im_session && im_session->mSessionType == LLIMModel::LLIMSession::GROUP_SESSION);
+	if(mIsGroupMsg)
+	{
+		mAvatarName->setValue(im_session->mName);
+		LLAvatarName avatar_name;
+		LLAvatarNameCache::get(p.avatar_id, &avatar_name);
+		p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message;
+	}
 	
 	//Handle IRC styled /me messages.
 	std::string prefix = p.message.substr(0, 4);
@@ -81,12 +91,17 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif
 		mMessage->setText(p.message, style_params);
 	}
 
-	mAvatarName->setValue(p.from);
+	if(!mIsGroupMsg)
+	{
+		mAvatarName->setValue(p.from);
+	}
 	mTime->setValue(p.time);
 	mSessionID = p.session_id;
 	mAvatarID = p.avatar_id;
 	mNotification = p.notification;
 
+
+
 	initIcon();
 
 	S32 maxLinesCount;
@@ -147,7 +162,14 @@ void LLToastIMPanel::spawnNameToolTip()
 
 	LLToolTip::Params params;
 	params.background_visible(false);
-	params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_avatar", LLSD().with("avatar_id", mAvatarID), FALSE));
+	if(!mIsGroupMsg)
+	{
+		params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_avatar", LLSD().with("avatar_id", mAvatarID), FALSE));
+	}
+	else
+	{
+		params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_group", LLSD().with("group_id", mSessionID), FALSE));
+	}
 	params.delay_time(0.0f);		// spawn instantly on hover
 	params.image(LLUI::getUIImage("Info_Small"));
 	params.message("");
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index 3eb11fb3bc6e157c1004036c43afa0502927c7f4..767617dabca83a746bd780f1392cc33161a39a83 100755
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -73,6 +73,8 @@ private:
 	LLTextBox*			mAvatarName;
 	LLTextBox*			mTime;
 	LLTextBox*			mMessage;
+
+	bool                mIsGroupMsg;
 };
 
 #endif // LLTOASTIMPANEL_H_
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index b2318f9158e8273c0eee654ff5170291c657cca9..78a555d67d3526083c6747d69af3710fbe794b45 100755
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -51,8 +51,6 @@ LLToolBarView* gToolBarView = NULL;
 
 static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
 
-void handleLoginToolbarSetup();
-
 bool isToolDragged()
 {
 	return (LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER);
@@ -111,8 +109,6 @@ BOOL LLToolBarView::postBuild()
 		mToolbars[i]->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded,_1));
 		mToolbars[i]->setButtonRemoveCallback(boost::bind(LLToolBarView::onToolBarButtonRemoved,_1));
 	}
-
-	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&handleLoginToolbarSetup));
 	
 	return TRUE;
 }
@@ -180,13 +176,13 @@ S32 LLToolBarView::stopCommandInProgress(const LLCommandId& commandId)
 	return command_location;
 }
 
-S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash)
+S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing/* = false */)
 {
 	S32 command_location = hasCommand(commandId);
 
 	if (command_location != TOOLBAR_NONE)
 	{
-		mToolbars[command_location]->flashCommand(commandId, flash);
+		mToolbars[command_location]->flashCommand(commandId, flash, force_flashing);
 	}
 
 	return command_location;
@@ -696,18 +692,3 @@ bool LLToolBarView::isModified() const
 }
 
 
-//
-// HACK to bring up destinations guide at startup
-//
-
-void handleLoginToolbarSetup()
-{
-	// Open the destinations guide by default on first login, per Rhett
-	if (gSavedPerAccountSettings.getBOOL("DisplayDestinationsOnInitialRun") || gAgent.isFirstLogin())
-	{
-		LLFloaterReg::showInstance("destinations");
-
-		gSavedPerAccountSettings.setBOOL("DisplayDestinationsOnInitialRun", FALSE);
-	}
-}
-
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 7125dd9990495e64bb020bdc760881480bbf8060..dcc38620746b70cc0c022fbb041bc73e8bea3cc3 100755
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -90,7 +90,7 @@ public:
 	S32 removeCommand(const LLCommandId& commandId, int& rank);	// Sets the rank the removed command was at, RANK_NONE if not found
 	S32 enableCommand(const LLCommandId& commandId, bool enabled);
 	S32 stopCommandInProgress(const LLCommandId& commandId);
-	S32 flashCommand(const LLCommandId& commandId, bool flash);
+	S32 flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing = false);
 
 	// Loads the toolbars from the existing user or default settings
 	bool loadToolbars(bool force_default = false);	// return false if load fails
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index afbb59e72343e2ea05404adc93d9f097d432e790..744ec4de2b02705f5605ff792df317d58dee2a03 100755
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -83,7 +83,9 @@
 BOOL 				gHackGodmode = FALSE;
 #endif
 
-
+// Should you contemplate changing the name "Global", please first grep for
+// that string literal. There are at least a couple other places in the C++
+// code that assume the LLControlGroup named "Global" is gSavedSettings.
 LLControlGroup gSavedSettings("Global");	// saved at end of session
 LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
 LLControlGroup gCrashSettings("CrashSettings");	// saved at end of session
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 0db118835c63d0c58fc033887eb908db273d7cd7..e3335c9cd859b333045e82fa30967e3b2dbc96f5 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -259,11 +259,15 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 		    break;
 	    }
 
-	    LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
-	    modified_form->setElementEnabled("Accept", false);
-	    modified_form->setElementEnabled("Decline", false);
-	    notification_ptr->updateForm(modified_form);
-	    notification_ptr->repost();
+		// TODO: this set of calls has undesirable behavior under Windows OS (CHUI-985):
+		// here appears three additional toasts instead one modified
+		// need investigation and fix
+
+	    // LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+	    // modified_form->setElementEnabled("Accept", false);
+	    // modified_form->setElementEnabled("Decline", false);
+	    // notification_ptr->updateForm(modified_form);
+	    // notification_ptr->repost();
     }
 
 	return false;
@@ -2649,7 +2653,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{
 				send_do_not_disturb_message(msg, from_id);
 			}
-			else
+			
+			if (!is_muted)
 			{
 				LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
 				// Read the binary bucket for more information.
@@ -3673,6 +3678,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		LLSD msg_notify = LLSD(LLSD::emptyMap());
 		msg_notify["session_id"] = LLUUID();
         msg_notify["from_id"] = chat.mFromID;
+		msg_notify["source_type"] = chat.mSourceType;
         on_new_message(msg_notify);
 	}
 }
@@ -5930,6 +5936,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
 				return true;
 			}
 		}
+		// HACK -- handle callbacks for specific alerts.
+		if( notificationID == "HomePositionSet" )
+		{
+			// save the home location image to disk
+			std::string snap_filename = gDirUtilp->getLindenUserDir();
+			snap_filename += gDirUtilp->getDirDelimiter();
+			snap_filename += SCREEN_HOME_FILENAME;
+			gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
+		}
 		
 		LLNotificationsUtil::add(notificationID, llsdBlock);
 		return true;
@@ -6005,14 +6020,6 @@ void process_alert_core(const std::string& message, BOOL modal)
 	{
 		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
 	}
-	else if( message == "Home position set." )
-	{
-		// save the home location image to disk
-		std::string snap_filename = gDirUtilp->getLindenUserDir();
-		snap_filename += gDirUtilp->getDirDelimiter();
-		snap_filename += SCREEN_HOME_FILENAME;
-		gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
-	}
 
 	const std::string ALERT_PREFIX("ALERT: ");
 	const std::string NOTIFY_PREFIX("NOTIFY: ");
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 97f4c3e5feb1e627f69494ed0852d15f8e81a8cf..e7821d4b9e489a43692d3b7013f1a95497d501e5 100755
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -43,6 +43,8 @@ const std::string  GRID_LABEL_VALUE = "label";
 const std::string  GRID_ID_VALUE = "grid_login_id";
 /// the url for the login cgi script
 const std::string  GRID_LOGIN_URI_VALUE = "login_uri";
+/// url base for update queries
+const std::string  GRID_UPDATE_SERVICE_URL = "update_query_url_base";
 ///
 const std::string  GRID_HELPER_URI_VALUE = "helper_uri";
 /// the splash page url
@@ -63,6 +65,8 @@ const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/"
 
 const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi";
 
+const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update";
+
 const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
 const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
 
@@ -120,12 +124,14 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  MAIN_GRID_LOGIN_URI,
 				  "https://secondlife.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
+				  SL_UPDATE_QUERY_URL,
 				  "Agni");
 	addSystemGrid("Second Life Beta Test Grid (Aditi)",
 				  "util.aditi.lindenlab.com",
 				  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
 				  "http://aditi-secondlife.webdev.lindenlab.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
+				  SL_UPDATE_QUERY_URL,
 				  "Aditi");
 
 	LLSD other_grids;
@@ -332,6 +338,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& login_uri,
 								  const std::string& helper,
 								  const std::string& login_page,
+								  const std::string& update_url_base,
 								  const std::string& login_id)
 {
 	LLSD grid = LLSD::emptyMap();
@@ -341,6 +348,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 	grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
 	grid[GRID_LOGIN_URI_VALUE].append(login_uri);
 	grid[GRID_LOGIN_PAGE_VALUE] = login_page;
+	grid[GRID_UPDATE_SERVICE_URL] = update_url_base;
 	grid[GRID_IS_SYSTEM_GRID_VALUE] = true;
 	grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
 	grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
@@ -537,6 +545,30 @@ std::string LLGridManager::getGridLoginID()
 	return mGridList[mGrid][GRID_ID_VALUE];
 }
 
+std::string LLGridManager::getUpdateServiceURL()
+{
+	std::string update_url_base = gSavedSettings.getString("CmdLineUpdateService");;
+	if ( !update_url_base.empty() )
+	{
+		LL_INFOS2("UpdaterService","GridManager")
+			<< "Update URL base overridden from command line: " << update_url_base
+			<< LL_ENDL;
+	}
+	else if ( mGridList[mGrid].has(GRID_UPDATE_SERVICE_URL) )
+	{
+		update_url_base = mGridList[mGrid][GRID_UPDATE_SERVICE_URL].asString();
+	}
+	else
+	{
+		LL_WARNS2("UpdaterService","GridManager")
+			<< "The grid property '" << GRID_UPDATE_SERVICE_URL
+			<< "' is not defined for the grid '" << mGrid << "'"
+			<< LL_ENDL;
+	}
+			
+	return update_url_base;
+}
+
 void LLGridManager::updateIsInProductionGrid()
 {
 	mIsInProductionGrid = false;
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 3f56103b2e72df1b1edfeaa7d903ba95987e8811..8526c0ba7f35959b41e90fc81b3a072d3f128b22 100755
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -139,6 +139,14 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	 * I am not sure which is which
 	 */
 
+	//@}
+	/* ================================================================
+	 * @name Update Related Properties
+	 * @{
+	 */
+	/// Get the update service URL base (host and path) for the selected grid
+	std::string getUpdateServiceURL();
+	
 	//@}
 
 	/* ================================================================
@@ -207,6 +215,7 @@ class LLGridManager : public LLSingleton<LLGridManager>
 					   const std::string& login, 
 					   const std::string& helper,
 					   const std::string& login_page,
+					   const std::string& update_url_base,
 					   const std::string& login_id = "");	
 	
 	
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 87ae224655cb87554a3dc2f13067ab5c0bbbc029..40b856007104ace5beb23386dc722785d25b21fe 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1813,7 +1813,6 @@ void LLViewerWindow::initBase()
 	gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
 	gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
 	gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
-	
 
 	// Console
 	llassert( !gConsole );
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index a9176595c7c0df87623b9344d8c7f6b960edc048..f53995732fb2bfdf63b59f8bfb9a075b6ca0f9dc 100755
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -884,4 +884,19 @@
   <color
     name="blue"
     value="0 0 1 1"/>
+
+  <!--Resize bar colors -->
+
+  <color
+    name="ResizebarBorderLight"
+    value="0.231 0.231 0.231 1"/>
+
+  <color
+    name="ResizebarBorderDark"
+    value="0.133 0.133 0.133 1"/>
+
+  <color
+    name="ResizebarBody"
+    value="0.208 0.208 0.208 1"/>
+    
 </colors>
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index b0e4b71d21554f3672ed08ceb70dc652c4b0cd5b..54f60f4441f309bdd2c391e0235cd597eaa68631 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -774,4 +774,7 @@ with the same filename but different name
   <texture name="Popup_Caution" file_name="icons/pop_up_caution.png"/>
   <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
   <texture name="NavBar Separator" file_name="navbar/separator.png"/>
+
+  <texture name="Horizontal Drag Handle" file_name="widgets/horizontal_drag_handle.png"/>
+  <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png"/>
 </textures>
diff --git a/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png b/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png
new file mode 100644
index 0000000000000000000000000000000000000000..642eac406553f2d704edf23cc04a9eba2272ca43
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png differ
diff --git a/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png b/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png
new file mode 100644
index 0000000000000000000000000000000000000000..b06b70cf36630d0dd7d43fa66fc5777c9db37805
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png differ
diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index fc8bc33096d17eb5a96f689fb1511afe9ef87da1..9206690c8f27a5b44a4effe44932dd4a11b4f28f 100755
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -8,7 +8,7 @@
 		Bygget med [COMPILER] version [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Du er ved [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] i regionen [REGION] lokaliseret ved &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 4387a619634bab5fd4f2b23cc7044ac666a632d7..524546718327f201848959feadbe37e16b616dbb 100755
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -8,7 +8,7 @@
 		Kompiliert mit [COMPILER] version [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Sie befinden sich in [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] auf &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Sie befinden sich in [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 63eb87f27a17531b618229d8883eaeb11119c0c1..703015af20081678693a8f0d72ad20312f1dd2e4 100755
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -22,7 +22,9 @@ Built with [COMPILER] version [COMPILER_VERSION]
 </floater.string>
   <floater.string
      name="AboutPosition">
-You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index 4e0cfb0cd4750e3502e3d5547e327754cbdc5a10..e7ab3cacdc4439086e723e68c0e079c540de60e0 100755
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -6,7 +6,7 @@
  layout="topleft"
  name="floaterbulkperms"
  help_topic="floaterbulkperms"
- title="EDIT CONTENT PERMISSIONS"
+ title="ADJUST CONTENT PERMISSIONS"
  width="410">
     <floater.string
      name="nothing_to_modify_text">
@@ -192,7 +192,7 @@
      name="newperms"
      top="90"
      width="250">
-        New Content Permissions
+        Adjust Content Permissions To
     </text>
       <text
        type="string"
@@ -292,9 +292,20 @@
      height="23"
      label="OK"
      layout="topleft"
-     left="205"
-     name="apply"
+     left="110"
+     name="ok"
      top_pad="10"
+     width="90">
+      <button.commit_callback
+       function="BulkPermission.Ok"/>
+    </button>
+    <button
+     follows="left|top"
+     height="23"
+     label="Apply"
+     layout="topleft"
+     left_pad="5"
+     name="apply"
      width="90">
       <button.commit_callback
        function="BulkPermission.Apply"/>
diff --git a/indra/newview/skins/default/xui/en/floater_goto_line.xml b/indra/newview/skins/default/xui/en/floater_goto_line.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2368882199bb3419fdce0c63309271c8fc53fe0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_goto_line.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ default_tab_group="1"
+ height="90"
+ layout="topleft"
+ name="script goto"
+ help_topic="script_goto"
+ title="GO TO LINE"
+ width="200">
+    <button
+     height="24"
+     label="OK"
+     label_selected="OK"
+     layout="topleft"
+     left="55"
+     name="goto_btn"
+     top="53"
+     width="90" />
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="16"
+     layout="topleft"
+     left="10"
+     name="txt"
+     top="21"
+     width="65">
+        Go to line
+    </text>
+    <line_editor
+     border_style="line"
+     border_thickness="1"
+     follows="left|top"
+     height="16"
+     layout="topleft"
+     left="75"
+     max_length_bytes="9"
+     name="goto_line"
+     tab_group="1"
+     top="21"
+     width="85" />
+</floater>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 65f623a47e88a7a86b233ef32c790a08a5e6c1e8..1215efb7f96478c879bf0c70d9bfaa693d01abe9 100755
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -4,6 +4,7 @@
  can_minimize="true"
  can_resize="true"
  height="210"
+ min_height="210"
  layout="topleft"
  name="floater_im_box"
  help_topic="floater_im_box"
@@ -24,24 +25,28 @@
      value="Conv_toolbar_expand"/>
     <layout_stack
      animate="true" 
-     bottom="-1"
+     bottom="-5"
+     drag_handle_gap="6"
+     drag_handle_first_indent="27"
+     drag_handle_second_indent="10"
      follows="all"
      layout="topleft"
      left="0"
      name="conversations_stack"
      orientation="horizontal"
      right="-1"
+     show_drag_handle="true"
      top="0">
         <layout_panel
          auto_resize="false"
          user_resize="true"        
          name="conversations_layout_panel"
          min_dim="38"
-         expanded_min_dim="156">
+         expanded_min_dim="136">
             <layout_stack
              animate="false" 
              follows="left|top|right"
-             height="35"
+             height="27"
              layout="topleft"
              left="0"
              name="conversations_pane_buttons_stack"
@@ -50,7 +55,6 @@
              top="0">
                 <layout_panel
                  auto_resize="true"
-                 height="35"
                  name="conversations_pane_buttons_expanded">
                     <menu_button
                      follows="top|left"
@@ -64,7 +68,7 @@
                      left="5"
                      name="sort_btn"
                      tool_tip="View/sort options"
-                     top="5"
+                     top="1"
                      width="31" />
                     <button
                      follows="top|left"
@@ -74,7 +78,7 @@
                      image_selected="Toolbar_Middle_Selected"
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
-                     top="5"
+                     top="1"
                      left_pad="2"
                      name="add_btn"
                      tool_tip="Start a new conversation"
@@ -87,7 +91,7 @@
                      image_selected="Toolbar_Middle_Selected"
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
-                     top="5"
+                     top="1"
                      left_pad="2"
                      name="speak_btn"
                      tool_tip="Speak with people using your microphone"
@@ -95,9 +99,8 @@
                 </layout_panel>
                 <layout_panel
                  auto_resize="false"
-                 height="35"
                  name="conversations_pane_buttons_collapsed"
-                 width="41">
+                 width="31">
                     <button
                      follows="right|top"
                      height="25"
@@ -106,8 +109,8 @@
                      image_selected="Toolbar_Middle_Selected"
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
-                     top="5"
-                     left="1"
+                     top="1"
+                     left="0"
                      name="expand_collapse_btn"
                      tool_tip="Collapse/Expand this list"
                      width="31" />
@@ -119,7 +122,7 @@
              layout="topleft"
              name="conversations_list_panel"
              opaque="true"
-             top="35"
+             top_pad="0"
              left="5"
              right="-1"/>
         </layout_panel>
@@ -127,7 +130,7 @@
          auto_resize="true"
          user_resize="true"
          name="messages_layout_panel"
-         expanded_min_dim="222">
+         expanded_min_dim="212">
             <panel_container
              bottom="-1"
              follows="all"
@@ -136,44 +139,44 @@
              name="im_box_tab_container"
              right="-1"
              top="0">
-             <panel
-               bottom="-1"
-               follows="all"
-               layout="topleft"
-               name="stub_panel"
-               opaque="true"
-               top_pad="0"
-               left="0"
-               right="-1">
-                 <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Conv_toolbar_collapse"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
+                <panel
+                 bottom="-1"
+                 follows="all"
                  layout="topleft"
-                 top="5"
-                 right="-10"
-                 name="stub_collapse_btn"
-                 tool_tip="Collapse this pane"
-                 width="31" />
-                 <text
-                   type="string"
-                   clip_partial="false"
-                   follows="left|top|right"
-                   layout="topleft"
-                   left="15"
-                   right="-15"
-                   name="stub_textbox"
-                   top="25"
-                   height="40"
-                   valign="center"
-                   parse_urls="true"
-                   wrap="true">
-                   This conversation is in a separate window.   [secondlife:/// Bring it back.]
-                 </text>
-             </panel>
+                 name="stub_panel"
+                 opaque="true"
+                 top_pad="0"
+                 left="0"
+                 right="-1">
+                    <button
+                     follows="right|top"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="Conv_toolbar_collapse"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     top="1"
+                     right="-10"
+                     name="stub_collapse_btn"
+                     tool_tip="Collapse this pane"
+                     width="31" />
+                    <text
+                     type="string"
+                     clip_partial="false"
+                     follows="left|top|right"
+                     layout="topleft"
+                     left="15"
+                     right="-15"
+                     name="stub_textbox"
+                     top="25"
+                     height="40"
+                     valign="center"
+                     parse_urls="true"
+                     wrap="true">
+                         This conversation is in a separate window.   [secondlife:/// Bring it back.]
+                    </text>
+                </panel>
             </panel_container>
         </layout_panel>
     </layout_stack>
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 2152a9f6e9acc944660c5ef7b3c1ae95d010e90c..43d0f2fb186975415af9240e522a00ef6d6942ef 100755
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -70,26 +70,23 @@
      top="0"
      left="0"
      right="-1"
-     bottom="-3">
+     bottom="-1">
         <layout_stack
          animate="false" 
+         bottom="-1"
          default_tab_group="2"
          follows="all"
-         right="-5"
-         bottom="-1"
-         top="0"
-         left="5"
-         border_size="0"
+         left="3"
          layout="topleft"
-         orientation="vertical"
          name="main_stack"
-         tab_group="1">
+         right="-3"
+         orientation="vertical"
+         tab_group="1"
+         top="0">
             <layout_panel
              auto_resize="false"
              name="toolbar_panel"
-             height="35"
-             right="-1"
-             left="1">
+             height="25">
                 <menu_button
                  menu_filename="menu_im_session_showmodes.xml"
                  follows="top|left"
@@ -102,7 +99,7 @@
                  left="5"
                  name="view_options_btn"
                  tool_tip="View/sort options"
-                 top="5"
+                 top="1"
                  width="31" />
                 <menu_button
                  menu_filename="menu_im_conversation.xml"
@@ -113,7 +110,7 @@
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 top="5"
+                 top="1"
                  left_pad="2"
                  name="gear_btn"
                  visible="false"
@@ -128,7 +125,7 @@
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 top="5"
+                 top="1"
                  left_pad="2"
                  name="add_btn"
                  tool_tip="Add someone to this conversation"
@@ -141,23 +138,11 @@
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 top="5"
+                 top="1"
                  left_pad="2"
                  name="voice_call_btn"
                  tool_tip="Open voice connection"
-                 width="31"/>
-                <output_monitor
-                 auto_update="true"
-                 follows="top|left"
-                 draw_border="false"
-                 height="16"
-                 layout="topleft"
-                 top="10"
-                 left_pad="10"
-                 mouse_opaque="true"
-                 name="speaking_indicator"
-                 visible="false"
-                 width="20" />
+                 width="31"/>                
                 <button
                  follows="right|top"
                  height="25"
@@ -166,8 +151,8 @@
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 top="5"
-                 right="-67"
+                 top="1"
+                 right="-70"
                  name="close_btn"
                  tool_tip="End this conversation"
                  width="31" />
@@ -179,7 +164,7 @@
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 top="5"
+                 top="1"
                  left_pad="2"
                  name="expand_collapse_btn"
                  tool_tip="Collapse/Expand this pane"
@@ -194,18 +179,21 @@
                  layout="topleft"
                  left_pad="2"
                  name="tear_off_btn"
-                 top="5"
+                 top="1"
                  width="31" />
             </layout_panel>
             <layout_panel
              name="body_panel"
-             top="1"
-             bottom="-1">
+             height="235">
                 <layout_stack
                  default_tab_group="2"
+                 drag_handle_gap="6"
+                 drag_handle_first_indent="0"
+                 drag_handle_second_indent="1"
                  follows="all"
                  orientation="horizontal"
                  name="im_panels"
+                 show_drag_handle="true"
                  tab_group="1"
                  top="0"
                  right="-1"
@@ -217,14 +205,12 @@
                      min_dim="0"
                      width="150" 
                      user_resize="true"
-                     auto_resize="false" 
-                     bottom="-1" />
+                     auto_resize="false" />
                     <layout_panel
                      default_tab_group="3"
                      tab_group="2"
                      name="right_part_holder"
-                     min_width="221"
-                     bottom="-1">
+                     min_width="172">
                         <layout_stack
                          animate="true" 
                          default_tab_group="2"
@@ -233,7 +219,7 @@
                          name="translate_and_chat_stack"
                          tab_group="1"
                          top="0"
-                         left="0"
+                         left="1"
                          right="-1"
                          bottom="-1">
                             <layout_panel
@@ -259,7 +245,7 @@
                                  parse_highlights="true"
                                  parse_urls="true"
                                  right="-1"
-                                 left="5"
+                                 left="0"
                                  top="0"
                                  bottom="-1" />
                             </layout_panel>
@@ -268,10 +254,7 @@
                 </layout_stack>
             </layout_panel>
             <layout_panel
-             top_delta="0"
-             top="0"
-             height="26"
-             bottom="-1"
+             height="35"
              auto_resize="false"
              name="chat_layout_panel">
                 <layout_stack
@@ -281,15 +264,11 @@
                  orientation="horizontal"
                  name="input_panels"
                  top="0"
-                 bottom="-2"
+                 bottom="-1"
                  left="0"
                  right="-1">
                     <layout_panel
-                     name="input_editor_layout_panel"
-                     auto_resize="true"
-                     user_resize="false"
-                     top="0"
-                     bottom="-1">
+                     name="input_editor_layout_panel">
                         <chat_editor
                          layout="topleft"
                          expand_lines_count="5"
@@ -302,32 +281,27 @@
                          max_length="1023"
                          spellcheck="true"
                          tab_group="3"
-                         top="1"
-                         bottom="-2"
-                         left="4"
-                         right="-4"
+                         bottom="-8"
+                         left="5"
+                         right="-5"
                          wrap="true" />
                     </layout_panel>
                     <layout_panel
                      auto_resize="false"
-                     user_resize="false"
                      name="input_button_layout_panel"
-                     width="30"
-                     top="0"
-                     bottom="-1">
+                     width="32">
                         <button
-                         layout="topleft"
                          left="1"
-                         right="-1"
-                         top="1"
-                         height="22"
+                         top="4"
+                         height="25"
                          follows="left|right|top"
                          image_hover_unselected="Toolbar_Middle_Over"
                          image_overlay="Conv_expand_one_line"
                          image_selected="Toolbar_Middle_Selected"
                          image_unselected="Toolbar_Middle_Off"
                          name="minz_btn"
-                         tool_tip="Shows/hides message panel" />
+                         tool_tip="Shows/hides message panel"
+                         width="28" />
                     </layout_panel>
                 </layout_stack>
             </layout_panel>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 5a13ef0a592f136d7e6c45845ac323a11e82a4fa..b3d28788da19817eec2ba77ab4b84e82fabcef0b 100755
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -11,7 +11,7 @@
      layout="topleft"
      name="close_conversation">
         <on_click function="Avatar.DoToSelected" parameter="close_conversation"/>
-	 </menu_item_call>
+	 </menu_item_call>	 
      <menu_item_call
      label="Open voice conversation"
      layout="topleft"
@@ -25,6 +25,12 @@
         <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/>
     </menu_item_call>	
 	<menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/>	
+	<menu_item_call
+     label="Close Selected"
+     layout="topleft"
+     name="close_selected_conversations">
+        <on_click function="Avatar.DoToSelected" parameter="close_selected_conversations"/>
+	 </menu_item_call>
     <menu_item_call
      label="View Profile"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index dde9432867a2609251a8791076a0c028208a29e7..8790fde7c5574c05437cd4c736d8dcca1cf38c7c 100755
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -44,6 +44,8 @@
     <menu_item_check.on_check
      function="Floater.Visible"
      parameter="conversation" />
+    <menu_item_check.on_enable
+     function="Conversation.IsConversationLoggingAllowed" />
     <menu_item_check.on_click
      function="Floater.Toggle"
      parameter="conversation" />
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index 7cd56f257a82808d1a31f4c978c618c6bd78a218..e8b6116026a90669a877477e5486ef19503f0963 100755
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -21,8 +21,15 @@
      layout="topleft"
      name="add_friend">
         <menu_item_call.on_click
-         function="Url.AddFriend" />        
+         function="Url.AddFriend" />
     </menu_item_call>
+    <menu_item_call
+     label="Remove Friend..."
+     layout="topleft"
+     name="remove_friend">
+        <menu_item_call.on_click
+         function="Url.RemoveFriend" />
+        </menu_item_call>
     <menu_item_separator
      layout="topleft" />
     <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
index 87ab58e622e70dcd717cee5fd35b2b2584b54674..b9d003b8419c244edfc95f9c391d0dfd001af118 100755
--- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
@@ -9,6 +9,13 @@
         <menu_item_call.on_click
          function="Url.Execute" />
     </menu_item_call>
+    <menu_item_call
+     label="Block..."
+     layout="topleft"
+     name="block_object">
+        <menu_item_call.on_click
+         function="Url.Block" />
+    </menu_item_call>
     <menu_item_separator
      layout="topleft" />
     <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b01c3067ff577179ba54528b9c7db7350bcf0978..f253ed3e06da98e7aa0dcd8b3c90f2896e3aded8 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -874,6 +874,15 @@
                  function="Tools.EnableSelectNextPart" />
             </menu_item_call>
         </menu>
+        <menu_item_call
+            label="Linksets..."
+            name="pathfinding_linkset_menu_item">
+          <menu_item_call.on_click
+              function="Floater.ToggleOrBringToFront"
+              parameter="pathfinding_linksets" />
+          <menu_item_call.on_enable
+              function="Tools.EnablePathfinding" />
+        </menu_item_call> 
         <menu_item_separator/>
 
         <menu_item_call
@@ -896,7 +905,7 @@
           <menu_item_call.on_enable
              function="Tools.SomethingSelectedNoHUD" />
         </menu_item_call>
-
+		 
         <menu_item_separator/>
 
         <menu
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 2e0e8bf8855f76ba56bb4d94b40c0c3789067553..ebd2799ebf8b3d1cbcc1c105acc74579115bbf6d 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -506,6 +506,33 @@ Add this Ability to &apos;[ROLE_NAME]&apos;?
      notext="No"
      yestext="Yes"/>
   </notification>
+  
+  <notification
+    icon="alertmodal.tga"
+    name="EjectGroupMemberWarning"
+    type="alertmodal">
+     You are about to eject [AVATAR_NAME] from the group.
+     <tag>group</tag>
+     <tag>confirm</tag>
+     <usetemplate
+      ignoretext="Confirm ejecting a participant from group"
+      name="okcancelignore"
+      notext="Cancel"
+      yestext="Eject"/>
+  </notification>
+  <notification
+    icon="alertmodal.tga"
+    name="EjectGroupMembersWarning"
+    type="alertmodal">
+     You are about to eject [COUNT] members from the group.
+     <tag>group</tag>
+     <tag>confirm</tag>
+     <usetemplate
+      ignoretext="Confirm ejecting multiple members from group"
+      name="okcancelignore"
+      notext="Cancel"
+      yestext="Eject"/>
+  </notification>
 
   <notification
    icon="alertmodal.tga"
@@ -2682,7 +2709,7 @@ Please enter a higher price.
    icon="alertmodal.tga"
    name="ConfirmItemDeleteHasLinks"
    type="alertmodal">
-At least one of the items you has link items that point to it.  If you delete this item, its links will permanently stop working.  It is strongly advised to delete the links first.
+At least one of the items has links that point to it.  If you delete this item, its links will permanently stop working.  It is strongly advised to delete the links first.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2724,7 +2751,7 @@ Are you sure you want to delete these items?
    icon="alertmodal.tga"
    name="ConfirmObjectDeleteNoOwn"
    type="alertmodal">
-You do not own least one of the items you have selected.
+You do not own at least one of the items you have selected.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2754,7 +2781,7 @@ Are you sure you want to delete these items?
    name="ConfirmObjectDeleteLockNoOwn"
    type="alertmodal">
 At least one object is locked.
-You do not own least one object.
+You do not own at least one object.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2769,7 +2796,7 @@ Are you sure you want to delete these items?
    name="ConfirmObjectDeleteNoCopyNoOwn"
    type="alertmodal">
 At least one object is not copyable.
-You do not own least one object.
+You do not own at least one object.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2785,13 +2812,13 @@ Are you sure you want to delete these items?
    type="alertmodal">
 At least one object is locked.
 At least one object is not copyable.
-You do not own least one object.
+You do not own at least one object.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
-     notext="cancel"
+     notext="Cancel"
      yestext="OK"/>
   </notification>
 
@@ -3708,6 +3735,17 @@ Leave Group?
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="OwnerCannotLeaveGroup"
+   type="alertmodal">
+    Unable to leave group. You cannot leave the group because you are the last owner of the group. Please assign another member to the owner role first.
+    <tag>group</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alert.tga"
    name="ConfirmKick"
@@ -5943,9 +5981,7 @@ Your calling card was declined.
    icon="notifytip.tga"
    name="TeleportToPerson"
    type="notifytip">
-    To contact Residents like &apos;[NAME]&apos;, click on the &quot;People&quot; button , select a Resident from the window that opens, then click &apos;IM&apos; at the
-    bottom of the window.
-    (You can also double-click on their name in the list, or right-click and choose &apos;IM&apos;).
+    To open a private conversation with someone, right-click on their avatar and choose &apos;IM&apos; from the menu.
   </notification>
 
   <notification
@@ -6573,7 +6609,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    icon="notify.tga"
    name="JoinGroup"
    persist="true"
-   type="notify">
+   type="offer">
     <tag>group</tag>
 [MESSAGE]
     <form name="form">
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 6d5fb51e85892d86d1836e4a89c8681629459821..c8ce5cdebf01c8b9d5db52bcb27bd519be7c3da0 100755
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -202,14 +202,14 @@ Maximum 200 per group daily
             Drag and drop item here to attach it:
         </text>
         <icon
-         height="72"
+         height="48"
          image_name="DropTarget"
          layout="topleft"
          left_pad="10"
          mouse_opaque="true"
          name="drop_icon"
          top_delta="-10"
-         width="72" />
+         width="110" />
         <button
          follows="left|top"
          layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 7ce2627be9931c2a59c629c4c4507d21aff5ad8e..ed274d02337bd81253c674aaf23e7faa1dca6f08 100755
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -480,10 +480,22 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                      function="People.Group.Minus" />
                 </dnd_button>
             </panel>
+            <text
+                type="string"
+                length="1"
+                follows="all"
+                height="14"
+                layout="topleft"
+                right="-10"
+                top_pad="4"
+                left="3"
+                name="groupcount">
+              You belong to [COUNT] groups, and can join [REMAINING] more.
+            </text>
             <group_list
              allow_select="true" 
              follows="all"
-             height="406"
+             height="388"
              layout="topleft"
              left="3"
              name="group_list"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 2cc9d9c1b075437557c7467dfb98f39bd61ad50a..50fd57494f91b60dff52895737381ba643716bfe 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -138,7 +138,7 @@
    initial_value="1"
    layout="topleft"
    left_pad="0"
-   max_val="1.4"
+   max_val="1.5"
    min_val="0.75"
    name="ui_scale_slider"
    top_pad="-14"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index bd096ebb885c1b7055c28769a7c7dff28d644718..8e867259c56b43e42a0e59f6338ba7e8cde435e4 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -14,6 +14,7 @@
       border="false"
       height="60"
       layout="topleft"
+      name="general_chat_settings" 
       top="10"
       left="13"
       width="517">
@@ -97,17 +98,10 @@
       border="false"
       height="165"
       layout="topleft"
+      name="im_notification_settings" 	
       left="13"
       width="517">
 
-    <text
-        layout="topleft"
-        height="12"
-        name="notifications"
-        left="0"
-        width="120">
-      Notifications
-    </text>
     <text
         layout="topleft"
         height="12"
@@ -138,17 +132,27 @@
           name="FlashToolbarButton"
           value="flash"/>
       <item
-          label="None"
-          name="None"
-          value="none"/>
+          label="No action"
+          name="NoAction"
+          value="noaction"/>
     </combo_box>
+    <check_box
+        control_name="PlaySoundFriendIM"
+        height="23"
+        label="Play sound"
+        layout="topleft"
+        name="play_sound_friend_im"
+        left_pad="7"
+        top_delta="-3"
+        width="28">
+    </check_box>
     <text
         layout="topleft"
         height="12"
         name="non_friend_ims"
         width="145"
         left="0"
-        top_pad="9">
+        top_pad="11">
       Non-friend IMs:
     </text>
     <combo_box
@@ -172,17 +176,27 @@
           name="FlashToolbarButton"
           value="flash"/>
       <item
-          label="None"
-          name="None"
-          value="none"/>
+          label="No action"
+          name="NoAction"
+          value="noaction"/>
     </combo_box>
+    <check_box
+        control_name="PlaySoundNonFriendIM"
+        height="23"
+        label="Play sound"
+        layout="topleft"
+        name="play_sound_non_friend_im"
+        left_pad="7"
+        top_delta="-3"
+        width="28">
+    </check_box>
     <text
         layout="topleft"
         left="0"
         height="13"
         name="conference_ims"
         width="145"
-        top_pad="9">
+        top_pad="11">
       Conference IMs:
     </text>
     <combo_box
@@ -206,17 +220,27 @@
           name="FlashToolbarButton"
           value="flash"/>
       <item
-          label="None"
-          name="None"
-          value="none"/>
+          label="No action"
+          name="NoAction"
+          value="noaction"/>
     </combo_box>
+    <check_box
+        control_name="PlaySoundConferenceIM"
+        height="23"
+        label="Play sound"
+        layout="topleft"
+        name="play_sound_conference_im"
+        left_pad="7"
+        top_delta="-3"
+        width="28">
+    </check_box>
     <text
         layout="topleft"
         left="0"
         height="13"
         name="group_chat"
         width="145"
-        top_pad="9">
+        top_pad="11">
       Group chat:
     </text>
     <combo_box
@@ -240,17 +264,27 @@
           name="FlashToolbarButton"
           value="flash"/>
       <item
-          label="None"
-          name="None"
-          value="none"/>
+          label="No action"
+          name="NoAction"
+          value="noaction"/>
     </combo_box>
+    <check_box
+        control_name="PlaySoundGroupChatIM"
+        height="23"
+        label="Play sound"
+        layout="topleft"
+        name="play_sound_group_chat_im"
+        left_pad="7"
+        top_delta="-3"
+        width="28">
+    </check_box>
     <text
         layout="topleft"
         left="0"
         height="12"
         name="nearby_chat"
         width="145"
-        top_pad="9">
+        top_pad="11">
       Nearby chat:
     </text>
     <combo_box
@@ -274,10 +308,64 @@
           name="FlashToolBarButton"
           value="flash"/>
       <item
-          label="None"
-          name="None"
-          value="none"/>
+          label="No action"
+          name="NoAction"
+          value="noaction"/>
     </combo_box>
+    <check_box
+        control_name="PlaySoundNearbyChatIM"
+        height="23"
+        label="Play sound"
+        layout="topleft"
+        name="play_sound_nearby_chat_im"
+        left_pad="7"
+        top_delta="-3"
+        width="28">
+    </check_box>
+    <text
+        layout="topleft"
+        left="0"
+        height="12"
+        name="object_ims"
+        width="145"
+        top_pad="11">
+      Object IMs:
+    </text>
+    <combo_box
+        control_name="NotificationObjectIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="ObjectIMOptions"
+        width="223">
+      <item
+          label="Open Conversations window"
+          name="OpenConversationsWindow"
+          value="openconversations"/>
+      <item
+          label="Pop up the message"
+          name="PopUpMessage"
+          value="toast"/>
+      <item
+          label="Flash toolbar button"
+          name="FlashToolBarButton"
+          value="flash"/>
+      <item
+          label="No action"
+          name="NoAction"
+          value="noaction"/>
+    </combo_box>
+    <check_box
+        control_name="PlaySoundObjectIM"
+        height="23"
+        label="Play sound"
+        layout="topleft"
+        name="play_sound_object_im"
+        left_pad="7"
+        top_delta="-3"
+        width="28">
+    </check_box>
     <text
         layout="topleft"
         left="0"
@@ -296,6 +384,7 @@
       border="false"
       height="50"
       layout="topleft"
+      name="play_sound_settings"  	
       left="13"
       top_pad="10"
       width="517">
@@ -358,6 +447,7 @@
   <panel
       height="50"
       layout="topleft"
+      name="log_settings" 	
       left="13"
       top_pad="10"
       width="505">
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 765b07ed8b36ab74a03c2dbcb3645764bcc4c958..bcdef96138127908cb98a4172587b41ec1da7606 100755
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -125,6 +125,10 @@
              label="Search / Replace..."
              layout="topleft"
              name="Search / Replace..." />
+            <menu_item_call
+             label="Go to line..."
+             layout="topleft"
+             name="Go to line..." />
         </menu>
         <menu
          top="0"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index d964ccaf796501cf41defec0a36bc0176f16b631..73601ecb9f45650efed5ca8cc41c9ab0fa0a658d 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -209,7 +209,8 @@ Please try logging in again in a minute.</string>
 	<string name="SLappAgentIM">IM</string>
 	<string name="SLappAgentPay">Pay</string>
 	<string name="SLappAgentOfferTeleport">Offer Teleport to </string>
-	<string name="SLappAgentRequestFriend">Friend Request </string>
+	<string name="SLappAgentRequestFriend">Friend Request</string>
+  <string name="SLappAgentRemoveFriend">Friend Removal</string>
 
 	<!-- ButtonToolTips, llfloater.cpp -->
 	<string name="BUTTON_CLOSE_DARWIN">Close (&#8984;W)</string>
@@ -3929,5 +3930,8 @@ Try enclosing path to the editor with double quotes.
   <string name="logging_calls_enabled_log_empty">
     There are no logged conversations. After you contact someone, or someone contacts you, a log entry will be shown here.
   </string>
+  <string name="loading_chat_logs">
+    Loading...
+  </string>
   
   </strings>
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 3696c7e12cfe6bc4ea349126b2612f28ebf70e41..7ca1e3721f48952bafa9d73296033b08219c2e77 100755
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -8,7 +8,7 @@
 		Compilado con [COMPILER], versión [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Estás en la posición [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1], de [REGION], alojada en &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index a659cb4245825c358dec94a8d3bc056fdafaa191..d45bdccf3e8f3e75f75fc2f0eb73ec6abe69017a 100755
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -8,7 +8,7 @@
 		Compilé avec [COMPILER] version [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Vous êtes à [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] dans [REGION], se trouvant à &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index c672511fc5a675edcc2515a8a22f2922677b59db..b0fb585fa252f9a118db2282639e6fa26b5a7afe 100755
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -8,7 +8,7 @@
 		Generato con [COMPILER] versione [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Tu sei  [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] che si trova a &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Tu sei  [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index 6d5df7564521497710b87166d5e4922f0b123d49..eae52c98ec2375af9c3aecadfb7a9fb1b6a1c37d 100755
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -8,7 +8,7 @@
 		コンパイラー [COMPILER] [COMPILER_VERSION] バージョン
 	</floater.string>
 	<floater.string name="AboutPosition">
-		あなたの現在地は、[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] の [REGION] です。位置は &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; です。([HOSTIP])
+		あなたの現在地は、[POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] の [REGION] です。位置は &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; です。([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml
index 409429ffaa64b2f5584ed937ebbce14fac9dc3fb..61a72ff27de35ec7a4870df323b5e882d4afaf6c 100755
--- a/indra/newview/skins/default/xui/pl/floater_about.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about.xml
@@ -8,7 +8,7 @@
 		Buduj z [COMPILER] wersjÄ… [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Położenie [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] w [REGION] zlokalizowanym w &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index 299f88b22a14211393417e5d8e0520cae587d399..d08926634208f1442c31cf58c7d69f83f8993413 100755
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -7,7 +7,7 @@
 		Construído com [COMPILER] versão [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em [HOSTNAME]&lt;/nolink&gt;([HOSTIP])
+		Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em [HOSTNAME]&lt;/nolink&gt;([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml
index bb6266ac9ae4196f593c2cef75cd74262fbd3f83..2b2b3cf453385abf54408b2fb5c3df30fe525ab2 100755
--- a/indra/newview/skins/default/xui/ru/floater_about.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about.xml
@@ -8,7 +8,7 @@
 		Использован компилятор [COMPILER], версия [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Вы в точке [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] в регионе «[REGION]», расположенном на &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Вы в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», расположенном на &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml
index 9cc9c7a2201ae01263d0ecd8a0ac53c07ce30a6e..4dcf6200c6377d7606f117da9062ee0a6449efed 100755
--- a/indra/newview/skins/default/xui/tr/floater_about.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about.xml
@@ -8,7 +8,7 @@
 		[COMPILER] [COMPILER_VERSION] sürümü ile oluşturuldu
 	</floater.string>
 	<floater.string name="AboutPosition">
-		&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] konumundasınız
+		&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml
index 643881e416e06e5fa9924085ccb4e01f152fc5e6..1193243c7ecbfeb4776c3099ff0a5ee74e1709f7 100755
--- a/indra/newview/skins/default/xui/zh/floater_about.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about.xml
@@ -8,7 +8,7 @@
 		以 [COMPILER_VERSION] 版本 [COMPILER] 建置
 	</floater.string>
 	<floater.string name="AboutPosition">
-		你的方位是 [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地區名:[REGION],主機:&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		你的方位是 [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地區名:[REGION],主機:&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index 3ba25f3c10963b160bfd1dc6a824b341d39cc1d2..a40b5c9a3d1836691d7ca0f2adeb1e77ad58158e 100755
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -49,10 +49,10 @@ LLControlGroup::~LLControlGroup()
 }
 
 // Implementation of just the LLControlGroup methods we requre
-BOOL LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	test_preferred_maturity = initial_val;
-	return true;
+	return NULL;
 }
 
 void LLControlGroup::setU32(const std::string& name, U32 val)
@@ -80,7 +80,7 @@ namespace tut
 	void agentaccess_object_t::test<1>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 		cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
@@ -109,7 +109,7 @@ namespace tut
 	void agentaccess_object_t::test<2>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 		// make sure default is PG
@@ -157,7 +157,7 @@ namespace tut
 	void agentaccess_object_t::test<3>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 #ifndef HACKED_GODLIKE_VIEWER
@@ -195,7 +195,7 @@ namespace tut
 	void agentaccess_object_t::test<4>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 #ifndef HACKED_GODLIKE_VIEWER
@@ -272,7 +272,7 @@ namespace tut
 	void agentaccess_object_t::test<5>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 		cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index f038112fd07ccf4ccea9bf7e6d78bea82450c343..adeb848e0338ab089c6d0f2a51933140692d7309 100755
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -135,6 +135,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& login, 
 								  const std::string& helper,
 								  const std::string& login_page,
+								  const std::string& update_url_base,
 								  const std::string& login_id)
 {
 }
@@ -175,8 +176,8 @@ F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }
 U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
 void LLControlGroup::setString(const std::string& name, const std::string& val) {}
 std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
-BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; }
-BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; }
+LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
+LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
 
 #include "lluicolortable.h"
 void LLUIColorTable::saveUserSettings(void)const {}
@@ -208,9 +209,7 @@ std::string const & LLUpdaterService::pumpName(void)
 	return wakka;
 }
 bool LLUpdaterService::updateReadyToInstall(void) { return false; }
-void LLUpdaterService::initialize(const std::string& url, 
-								  const std::string& path,
-								  const std::string& channel,
+void LLUpdaterService::initialize(const std::string& channel,
 								  const std::string& version,
 								  const std::string& platform,
 								  const std::string& platform_version,
@@ -344,13 +343,13 @@ namespace tut
 			gTOSReplyPump = 0; // clear the callback.
 
 
-			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE);
-			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE);
-			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
-			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
-			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
-			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
-			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
+			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);
 
 			LLSD authenticator = LLSD::emptyMap();
 			LLSD identifier = LLSD::emptyMap();
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index 703603e2dbff8911f91ad9bebff4ada5728149ee..d7e87ed52ea5dc0c1a8d9c9853a358774c1fd180 100755
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -39,10 +39,10 @@
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 std::string LLControlGroup::getString(const std::string& name)
 {
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 02354009760348c40dd7bc1b294d250a9ed0a449..2a8dc153466a7ee12efe56f815d7f027c9774855 100755
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -71,10 +71,10 @@ std::string gLastName;
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 std::string LLControlGroup::getString(const std::string& name)
 {
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index 09343ef227b209efdc0ecc8ce7522dddc7dcd5f4..86229ad636b1b7ced88daed66d231177e6a23257 100755
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -37,10 +37,10 @@
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 
 std::string gCmdLineLoginURI;
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
index 710881d81124587d8dcb5512a030732880b87c8b..f6456a28392b5af902743800117c0c60203f4127 100755
--- a/indra/newview/tests/llviewerhelputil_test.cpp
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -49,10 +49,10 @@ static std::string gOS;
 LLControlGroup::LLControlGroup(const std::string& name)
 	: LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
 				   const std::string& initial_val,
 				   const std::string& comment,
-				   BOOL persist) {return TRUE;}
+				   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 std::string LLControlGroup::getString(const std::string& name)
 {
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index a1e97ea17eac6641eb0788d97b0fa1a1aac1e595..7ad7947ca43ec3c0d0ef847759fd6d2311719fbb 100755
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -37,10 +37,10 @@
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 
 std::string gCmdLineLoginURI;
@@ -127,6 +127,7 @@ const char *gSampleGridFile =
 	"      <array>"
 	"        <string>myloginuri</string>"
 	"      </array>"
+	"      <key>update_query_url_base</key><string>https://update.secondlife.com/update</string>"
 	"      <key>keyname</key><string>util.foobar.lindenlab.com</string>"
 	"    </map>"
 	"  </map>"
@@ -185,6 +186,9 @@ namespace tut
 		ensure_equals("id for agni",
 					  std::string("Agni"),
 					  LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"));
+		ensure_equals("update url base for Agni", // relies on agni being the default
+					  std::string("https://update.secondlife.com/update"),
+					  LLGridManager::getInstance()->getUpdateServiceURL());
 		ensure_equals("label for agni",
 					  LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
 					  std::string("Second Life Main Grid (Agni)"));
@@ -256,6 +260,9 @@ namespace tut
 		ensure_equals("id for agni",
 					  LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"),
 					  std::string("Agni"));
+		ensure_equals("update url base for Agni", // relies on agni being the default
+					  std::string("https://update.secondlife.com/update"),
+					  LLGridManager::getInstance()->getUpdateServiceURL());
 		ensure_equals("label for agni",
 					  LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
 					  std::string("Second Life Main Grid (Agni)"));
@@ -384,6 +391,9 @@ namespace tut
 		ensure_equals("getLoginPage",
 					  LLGridManager::getInstance()->getLoginPage(),
 					  std::string("http://viewer-login.agni.lindenlab.com/"));
+		ensure_equals("update url base for Agni", // relies on agni being the default
+					  std::string("https://update.secondlife.com/update"),
+					  LLGridManager::getInstance()->getUpdateServiceURL());
 		ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid());
 		std::vector<std::string> uris;
 		LLGridManager::getInstance()->getLoginURIs(uris);
diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp
index 711c2a3d51a908ba9a18316556c49f643d1c1960..20f913b67083be6aeef3635428f8dbb9b2a35d90 100755
--- a/indra/newview/tests/llxmlrpclistener_test.cpp
+++ b/indra/newview/tests/llxmlrpclistener_test.cpp
@@ -62,8 +62,8 @@ namespace tut
             // These variables are required by machinery used by
             // LLXMLRPCTransaction. The values reflect reality for this test
             // executable; hopefully these values are correct.
-            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist
-            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist
+            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist
+            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist
         }
 
         // LLEventPump listener signature
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 5e08e54b7c6de60882f99a135e607a8957065278..19863dd84548f7eb077899f97dfb55a2fdcaeb7a 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -34,9 +34,15 @@ import tarfile
 import time
 import random
 viewer_dir = os.path.dirname(__file__)
-# add llmanifest library to our path so we don't have to muck with PYTHONPATH
-sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
-from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+# Add indra/lib/python to our path so we don't have to muck with PYTHONPATH.
+# Put it FIRST because some of our build hosts have an ancient install of
+# indra.util.llmanifest under their system Python!
+sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python"))
+from indra.util.llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+try:
+    from llbase import llsd
+except ImportError:
+    from indra.base import llsd
 
 class ViewerManifest(LLManifest):
     def is_packaging_viewer(self):
@@ -65,13 +71,13 @@ class ViewerManifest(LLManifest):
                 # include the entire shaders directory recursively
                 self.path("shaders")
                 # include the extracted list of contributors
-                contributor_names = self.extract_names("../../doc/contributions.txt")
-                self.put_in_file(contributor_names, "contributors.txt")
-                self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")])
+                contributions_path = "../../doc/contributions.txt"
+                contributor_names = self.extract_names(contributions_path)
+                self.put_in_file(contributor_names, "contributors.txt", src=contributions_path)
                 # include the extracted list of translators
-                translator_names = self.extract_names("../../doc/translations.txt")
-                self.put_in_file(translator_names, "translators.txt")
-                self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")])
+                translations_path = "../../doc/translations.txt"
+                translator_names = self.extract_names(translations_path)
+                self.put_in_file(translator_names, "translators.txt", src=translations_path)
                 # include the list of Lindens (if any)
                 #   see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits
                 linden_names_path = os.getenv("LINDEN_CREDITS")
@@ -85,10 +91,9 @@ class ViewerManifest(LLManifest):
                     else:
                          # all names should be one line, but the join below also converts to a string
                         linden_names = ', '.join(linden_file.readlines())
-                        self.put_in_file(linden_names, "lindens.txt")
+                        self.put_in_file(linden_names, "lindens.txt", src=linden_names_path)
                         linden_file.close()
                         print "Linden names extracted from '%s'" % linden_names_path
-                        self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")])
 
                 # ... and the entire windlight directory
                 self.path("windlight")
@@ -99,6 +104,27 @@ class ViewerManifest(LLManifest):
                     self.path("dictionaries")
                     self.end_prefix(pkgdir)
 
+                # CHOP-955: If we have "sourceid" in the build process
+                # environment, generate it into settings_install.xml.
+                try:
+                    sourceid = os.environ["sourceid"]
+                except KeyError:
+                    # no sourceid, no settings_install.xml file
+                    pass
+                else:
+                    if sourceid:
+                        # Single-entry subset of the LLSD content of settings.xml
+                        content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers',
+                                                     Persist=1,
+                                                     Type='String',
+                                                     Value=sourceid))
+                        # put_in_file(src=) need not be an actual pathname; it
+                        # only needs to be non-empty
+                        settings_install = self.put_in_file(llsd.format_pretty_xml(content),
+                                                            "settings_install.xml",
+                                                            src="environment")
+                        print "Put sourceid '%s' in %s" % (sourceid, settings_install)
+
                 self.end_prefix("app_settings")
 
             if self.prefix(src="character"):
@@ -196,24 +222,26 @@ class ViewerManifest(LLManifest):
         """ Convenience function that returns the command-line flags
         for the grid"""
 
-        # Set command line flags relating to the target grid
-        grid_flags = ''
-        if not self.default_grid():
-            grid_flags = "--grid %(grid)s "\
-                         "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\
-                           {'grid':self.grid()}
-
-        # Deal with settings 
-        setting_flags = ''
-        if not self.default_channel() or not self.default_grid():
-            if self.default_grid():
-                setting_flags = '--settings settings_%s.xml'\
-                                % self.channel_lowerword()
-            else:
-                setting_flags = '--settings settings_%s_%s.xml'\
-                                % (self.grid(), self.channel_lowerword())
-                                                
-        return " ".join((grid_flags, setting_flags)).strip()
+        # The original role of this method seems to have been to build a
+        # grid-specific viewer: one that would, on launch, preselect a
+        # particular grid. (Apparently that dates back to when the protocol
+        # between viewer and simulator required them to be updated in
+        # lockstep, so that "the beta grid" required "a beta viewer.") But
+        # those viewer command-line switches no longer work without tweaking
+        # user_settings/grids.xml. In fact, going forward, it's unclear what
+        # use case that would address.
+
+        # This method also set a channel-specific (or grid-and-channel-
+        # specific) user_settings/settings_something.xml file. It has become
+        # clear that saving user settings in a channel-specific file causes
+        # more problems (confusion) than it solves, so we've discontinued that.
+
+        # In fact we now avoid forcing viewer command-line switches at all,
+        # instead introducing a settings_install.xml file. Command-line
+        # switches don't aggregate well; for instance the generated --channel
+        # switch actually prevented the user specifying --channel on the
+        # command line. Settings files have well-defined override semantics.
+        return None
 
     def extract_names(self,src):
         try:
@@ -530,8 +558,7 @@ class WindowsManifest(ViewerManifest):
             'final_exe' : self.final_exe(),
             'grid':self.args['grid'],
             'grid_caps':self.args['grid'].upper(),
-            # escape quotes becase NSIS doesn't handle them well
-            'flags':self.flags_list().replace('"', '$\\"'),
+            'flags':'',
             'channel':self.channel(),
             'channel_oneword':self.channel_oneword(),
             'channel_unique':self.channel_unique(),
@@ -759,9 +786,6 @@ class DarwinManifest(ViewerManifest):
 
                     self.end_prefix("llplugin")
 
-                # command line arguments for connecting to the proper grid
-                self.put_in_file(self.flags_list(), 'arguments.txt')
-
                 self.end_prefix("Resources")
 
             self.end_prefix("Contents")
@@ -807,10 +831,6 @@ class DarwinManifest(ViewerManifest):
                                  'bundle': self.get_dst_prefix()
                 })
 
-        channel_standin = 'Second Life Viewer'  # hah, our default channel is not usable on its own
-        if not self.default_channel():
-            channel_standin = self.channel()
-
         imagename="SecondLife_" + '_'.join(self.args['version'])
 
         # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
@@ -928,9 +948,6 @@ class LinuxManifest(ViewerManifest):
             self.path("install.sh")
             self.end_prefix("linux_tools")
 
-        # Create an appropriate gridargs.dat for this package, denoting required grid.
-        self.put_in_file(self.flags_list(), 'etc/gridargs.dat')
-
         if self.prefix(src="", dst="bin"):
             self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
             self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 1e768f52d9d5ebac40a3e5eadbbbaf3f1e49029b..91a5f9246eb86f0420a4f44b2b1736f62535d07f 100755
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -62,8 +62,7 @@ LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
 }
 
 
-void LLUpdateChecker::checkVersion(std::string const & hostUrl, 
-								   std::string const & servicePath,
+void LLUpdateChecker::checkVersion(std::string const & urlBase, 
 								   std::string const & channel,
 								   std::string const & version,
 								   std::string const & platform,
@@ -71,7 +70,7 @@ void LLUpdateChecker::checkVersion(std::string const & hostUrl,
 								   unsigned char       uniqueid[MD5HEX_STR_SIZE],
 								   bool                willing_to_test)
 {
-	mImplementation->checkVersion(hostUrl, servicePath, channel, version, platform, platform_version, uniqueid, willing_to_test);
+	mImplementation->checkVersion(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
 }
 
 
@@ -99,8 +98,7 @@ LLUpdateChecker::Implementation::~Implementation()
 }
 
 
-void LLUpdateChecker::Implementation::checkVersion(std::string const & hostUrl, 
-												   std::string const & servicePath,
+void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase, 
 												   std::string const & channel,
 												   std::string const & version,
 												   std::string const & platform,
@@ -112,8 +110,7 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & hostUrl,
 	{
 		mInProgress = true;
 
-		mHostUrl     	 = hostUrl;
-		mServicePath 	 = servicePath;
+		mUrlBase     	 = urlBase;
 		mChannel     	 = channel;
 		mVersion     	 = version;
 		mPlatform        = platform;
@@ -123,7 +120,7 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & hostUrl,
 	
 		mProtocol = sProtocolVersion;
 
-		std::string checkUrl = buildUrl(hostUrl, servicePath, channel, version, platform, platform_version, uniqueid, willing_to_test);
+		std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
 		LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL;
 	
 		mHttpClient.get(checkUrl, this);
@@ -158,7 +155,7 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 			if (mProtocol == sProtocolVersion)
 			{
 				mProtocol = sLegacyProtocolVersion;
-				std::string retryUrl = buildUrl(mHostUrl, mServicePath, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
+				std::string retryUrl = buildUrl(mUrlBase, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
 
 				LL_WARNS("UpdaterService")
 					<< "update response using " << sProtocolVersion
@@ -203,8 +200,7 @@ void LLUpdateChecker::Implementation::error(U32 status, const std::string & reas
 }
 
 
-std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUrl, 
-													  std::string const & servicePath,
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase, 
 													  std::string const & channel,
 													  std::string const & version,
 													  std::string const & platform,
@@ -213,7 +209,6 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUr
 													  bool                willing_to_test)
 {	
 	LLSD path;
-	path.append(servicePath);
 	path.append(mProtocol);
 	path.append(channel);
 	path.append(version);
@@ -224,5 +219,5 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUr
 		path.append(willing_to_test ? "testok" : "testno");
 		path.append((char*)uniqueid);
 	}
-	return LLURI::buildHTTP(hostUrl, path).asString();
+	return LLURI::buildHTTP(urlBase, path).asString();
 }
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index 8e8558749030b5368b143612b00e431a345bfa6f..4244007340103b2274fa027377bdfa9bd821031b 100755
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -43,8 +43,7 @@ public:
 	public:
 		Implementation(Client & client);
 		~Implementation();
-		void checkVersion(std::string const & hostUrl, 
-						  std::string const & servicePath,
+		void checkVersion(std::string const & urlBase, 
 						  std::string const & channel,
 						  std::string const & version,
 						  std::string const & platform,
@@ -68,16 +67,14 @@ public:
 		LLHTTPClient mHttpClient;
 		bool         mInProgress;
 		std::string   mVersion;
-		std::string   mHostUrl;
-		std::string   mServicePath;
+		std::string   mUrlBase;
 		std::string   mChannel;
 		std::string   mPlatform;
 		std::string   mPlatformVersion;
 		unsigned char mUniqueId[MD5HEX_STR_SIZE];
 		bool          mWillingToTest;
 		
-		std::string buildUrl(std::string const & hostUrl, 
-							 std::string const & servicePath,
+		std::string buildUrl(std::string const & urlBase, 
 							 std::string const & channel,
 							 std::string const & version,
 							 std::string const & platform,
@@ -95,8 +92,7 @@ public:
 	LLUpdateChecker(Client & client);
 	
 	// Check status of current app on the given host for the channel and version provided.
-	void checkVersion(std::string const & hostUrl, 
-					  std::string const & servicePath,
+	void checkVersion(std::string const & urlBase, 
 					  std::string const & channel,
 					  std::string const & version,
 					  std::string const & platform,
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 1bd9fa4fc0f30c533b912a243b6ac58f66bb1858..16950e1d62ea821010119022e227c2b7ecba3654 100755
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -38,6 +38,7 @@
 #include "lldir.h"
 #include "llsdserialize.h"
 #include "llfile.h"
+#include "llviewernetwork.h"
 
 #if LL_WINDOWS
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
@@ -93,8 +94,6 @@ class LLUpdaterServiceImpl :
 	static const std::string sListenerName;
 	
 	std::string   mProtocolVersion;
-	std::string   mUrl;
-	std::string   mPath;
 	std::string   mChannel;
 	std::string   mVersion;
 	std::string   mPlatform;
@@ -120,9 +119,7 @@ public:
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl();
 
-	void initialize(const std::string& 	url, 
-					const std::string& 	path,
-					const std::string& 	channel,
+	void initialize(const std::string& 	channel,
 					const std::string& 	version,
 					const std::string&  platform,
 					const std::string&  platform_version,
@@ -183,9 +180,7 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 }
 
-void LLUpdaterServiceImpl::initialize(const std::string&  url, 
-									  const std::string&  path,
-									  const std::string&  channel,
+void LLUpdaterServiceImpl::initialize(const std::string&  channel,
 									  const std::string&  version,
 									  const std::string&  platform,
 									  const std::string&  platform_version,
@@ -198,8 +193,6 @@ void LLUpdaterServiceImpl::initialize(const std::string&  url,
 										   "while updater is running.");
 	}
 		
-	mUrl = url;
-	mPath = path;
 	mChannel = channel;
 	mVersion = version;
 	mPlatform = platform;
@@ -207,8 +200,6 @@ void LLUpdaterServiceImpl::initialize(const std::string&  url,
 	memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE);
 	mWillingToTest = willing_to_test;
 	LL_DEBUGS("UpdaterService")
-		<< "\n  url: " << mUrl
-		<< "\n  path: " << mPath
 		<< "\n  channel: " << mChannel
 		<< "\n  version: " << mVersion
 		<< "\n  uniqueid: " << mUniqueId
@@ -228,7 +219,7 @@ void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond)
 
 void LLUpdaterServiceImpl::startChecking(bool install_if_ready)
 {
-	if(mUrl.empty() || mChannel.empty() || mVersion.empty())
+	if(mChannel.empty() || mVersion.empty())
 	{
 		throw LLUpdaterService::UsageError("Set params before call to "
 			"LLUpdaterService::startCheck().");
@@ -415,7 +406,7 @@ void LLUpdaterServiceImpl::response(LLSD const & content)
 	
 		setState(LLUpdaterService::UP_TO_DATE);
 	}
-	else
+	else if ( content.isMap() && content.has("url") )
 	{
 		// there is an update available...
 		stopTimer();
@@ -439,6 +430,12 @@ void LLUpdaterServiceImpl::response(LLSD const & content)
 			<< LL_ENDL;
 		mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required);
 	}
+	else
+	{
+		LL_WARNS("UpdaterService") << "Invalid update query response ignored; retry in "
+								   << mCheckPeriod << " seconds" << LL_ENDL;
+		restartTimer(mCheckPeriod);
+	}
 }
 
 void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) 
@@ -565,8 +562,26 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 		}
 		else
 		{
-			mUpdateChecker.checkVersion(mUrl, mPath, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
-			setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+			std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL();
+			if ( !query_url.empty() )
+			{
+				mUpdateChecker.checkVersion(query_url, mChannel, mVersion,
+											mPlatform, mPlatformVersion, mUniqueId,
+											mWillingToTest);
+				setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+			}
+			else
+			{
+				LL_WARNS("UpdaterService")
+					<< "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid()
+					<< "' will check again in " << mCheckPeriod << " seconds"
+					<< LL_ENDL;
+				// Because the grid can be changed after the viewer is started (when the first check takes place)
+				// but before the user logs in, the next check may be on a different grid, so set the retry timer
+				// even though this check did not happen.  The default time is once an hour, and if we're not
+				// doing the check anyway the performance impact is completely insignificant.
+				restartTimer(mCheckPeriod);
+			}
 		}
 	} 
 	else 
@@ -610,9 +625,7 @@ LLUpdaterService::~LLUpdaterService()
 {
 }
 
-void LLUpdaterService::initialize(const std::string& url, 
-								  const std::string& path,
-								  const std::string& channel,
+void LLUpdaterService::initialize(const std::string& channel,
 								  const std::string& version,
 								  const std::string& platform,
 								  const std::string& platform_version,
@@ -620,7 +633,7 @@ void LLUpdaterService::initialize(const std::string& url,
 								  const bool&         willing_to_test
 )
 {
-	mImpl->initialize(url, path, channel, version, platform, platform_version, uniqueid, willing_to_test);
+	mImpl->initialize(channel, version, platform, platform_version, uniqueid, willing_to_test);
 }
 
 void LLUpdaterService::setCheckPeriod(unsigned int seconds)
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 982f99b86135032c26842c93373356331e516ce3..0ddf24935b173bc77c5cb4abf5d6e3607e389dda 100755
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -71,9 +71,7 @@ public:
 	LLUpdaterService();
 	~LLUpdaterService();
 
-	void initialize(const std::string& 	url, 
-				    const std::string& 	path,
-				    const std::string& 	channel,
+	void initialize(const std::string& 	channel,
 				    const std::string& 	version,
 					const std::string&  platform,
 					const std::string&  platform_version,
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
index a9df9042fda2a029d55cbef46f707926b06cafc9..03089f192e899b2d82c33d43ea02fdb7c495a9c0 100755
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -69,8 +69,11 @@ then # zenity on PATH and is executable
          # clear any previous message
          clear_message
          # put up a new zenity box and capture its pid
-         "$zenpath" --info --title "Second Life Viewer Updater" \
-                    --width=320 --height=120 --text="$*" &
+##       "$zenpath" --info --title "Second Life Viewer Updater" \
+##                  --width=320 --height=120 --text="$*" &
+         # MAINT-2333: use bouncing progress bar
+         "$zenpath" --progress --pulsate --no-cancel --title "Second Life Viewer Updater" \
+                    --width=320 --height=120 --text "$*" </dev/null &
          statuspid=$!
      }
 
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 4812272ebc12c919f97a692ef1edf5825d40e0f1..759e41ef4c1823c3f837a750424627eb12941aab 100755
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -44,8 +44,7 @@
 *****************************************************************************/
 LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
 {}
-void LLUpdateChecker::checkVersion(std::string const & hostUrl, 
-								   std::string const & servicePath,
+void LLUpdateChecker::checkVersion(std::string const & urlBase, 
 								   std::string const & channel,
 								   std::string const & version,
 								   std::string const & platform,
@@ -91,6 +90,21 @@ bool LLDir::setCacheDir(const std::string &path){ return true; }
 void LLDir::dumpCurrentDirectories() {}
 void LLDir::updatePerAccountChatLogsDir() {}
 
+#include "llviewernetwork.h"
+LLGridManager::LLGridManager() :
+	mGrid("test.grid.lindenlab.com"),
+	mIsInProductionGrid(false)
+{
+}
+std::string LLGridManager::getUpdateServiceURL()
+{
+	return "https://update.secondlife.com/update";
+}
+LLGridManager::~LLGridManager()
+{
+}
+
+
 std::string LLDir::getExpandedFilename(ELLPath location, 
 									   const std::string &filename) const 
 {
@@ -179,10 +193,10 @@ namespace tut
 		try
 		{
 			unsigned char id1[MD5HEX_STR_SIZE] = "11111111111111111111111111111111";
-			updater.initialize(test_url, "update" ,test_channel, test_version, "win", "1.2.3", id1, true);
+			updater.initialize(test_channel, test_version, "win", "1.2.3", id1, true);
 			updater.startChecking();
 			unsigned char id2[MD5HEX_STR_SIZE] = "22222222222222222222222222222222";
-			updater.initialize("other_url", "update", test_channel, test_version, "win", "4.5.6", id2, true);
+			updater.initialize(test_channel, test_version, "win", "4.5.6", id2, true);
 		}
 		catch(LLUpdaterService::UsageError)
 		{
@@ -197,7 +211,7 @@ namespace tut
         DEBUG;
 		LLUpdaterService updater;
 		unsigned char id[MD5HEX_STR_SIZE] = "33333333333333333333333333333333";
-		updater.initialize(test_url, "update", test_channel, test_version, "win", "7.8.9", id, true);
+		updater.initialize(test_channel, test_version, "win", "7.8.9", id, true);
 		updater.startChecking();
 		ensure(updater.isChecking());
 		updater.stopChecking();